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/frame/Settings.h"
56 #include "core/html/HTMLFrameElement.h"
57 #include "core/page/Page.h"
58 #include "core/page/scrolling/ScrollingCoordinator.h"
59 #include "core/rendering/ColumnInfo.h"
60 #include "core/rendering/FilterEffectRenderer.h"
61 #include "core/rendering/HitTestRequest.h"
62 #include "core/rendering/HitTestResult.h"
63 #include "core/rendering/HitTestingTransformState.h"
64 #include "core/rendering/RenderFlowThread.h"
65 #include "core/rendering/RenderGeometryMap.h"
66 #include "core/rendering/RenderInline.h"
67 #include "core/rendering/RenderPart.h"
68 #include "core/rendering/RenderReplica.h"
69 #include "core/rendering/RenderScrollbar.h"
70 #include "core/rendering/RenderScrollbarPart.h"
71 #include "core/rendering/RenderTreeAsText.h"
72 #include "core/rendering/RenderView.h"
73 #include "core/rendering/compositing/CompositedLayerMapping.h"
74 #include "core/rendering/compositing/RenderLayerCompositor.h"
75 #include "core/rendering/svg/ReferenceFilterBuilder.h"
76 #include "core/rendering/svg/RenderSVGResourceClipper.h"
77 #include "platform/LengthFunctions.h"
78 #include "platform/Partitions.h"
79 #include "platform/RuntimeEnabledFeatures.h"
80 #include "platform/TraceEvent.h"
81 #include "platform/geometry/FloatPoint3D.h"
82 #include "platform/geometry/FloatRect.h"
83 #include "platform/geometry/TransformState.h"
84 #include "platform/graphics/GraphicsContextStateSaver.h"
85 #include "platform/graphics/filters/ReferenceFilter.h"
86 #include "platform/graphics/filters/SourceGraphic.h"
87 #include "platform/transforms/ScaleTransformOperation.h"
88 #include "platform/transforms/TransformationMatrix.h"
89 #include "platform/transforms/TranslateTransformOperation.h"
90 #include "public/platform/Platform.h"
91 #include "wtf/StdLibExtras.h"
92 #include "wtf/text/CString.h"
98 static CompositingQueryMode gCompositingQueryMode =
99 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases;
103 using namespace HTMLNames;
105 RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
107 , m_hasSelfPaintingLayerDescendant(false)
108 , m_hasSelfPaintingLayerDescendantDirty(false)
109 , m_isRootLayer(renderer->isRenderView())
110 , m_usedTransparency(false)
111 , m_visibleContentStatusDirty(true)
112 , m_hasVisibleContent(false)
113 , m_visibleDescendantStatusDirty(false)
114 , m_hasVisibleDescendant(false)
115 , m_hasVisibleNonLayerContent(false)
116 , m_isPaginated(false)
117 , m_3DTransformedDescendantStatusDirty(true)
118 , m_has3DTransformedDescendant(false)
119 , m_containsDirtyOverlayScrollbars(false)
120 , m_hasFilterInfo(false)
121 , m_needsAncestorDependentCompositingInputsUpdate(true)
122 , m_needsDescendantDependentCompositingInputsUpdate(true)
123 , m_childNeedsCompositingInputsUpdate(true)
124 , m_hasCompositingDescendant(false)
125 , m_hasNonCompositedChild(false)
126 , m_shouldIsolateCompositedDescendants(false)
127 , m_lostGroupedMapping(false)
128 , m_renderer(renderer)
134 , m_staticInlinePosition(0)
135 , m_staticBlockPosition(0)
136 , m_enclosingPaginationLayer(0)
137 , m_potentialCompositingReasonsFromStyle(CompositingReasonNone)
138 , m_compositingReasons(CompositingReasonNone)
139 , m_groupedMapping(0)
140 , m_clipper(*renderer)
142 updateStackingNode();
144 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
146 if (!renderer->slowFirstChild() && renderer->style()) {
147 m_visibleContentStatusDirty = false;
148 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
151 updateScrollableArea();
154 RenderLayer::~RenderLayer()
156 if (renderer()->frame() && renderer()->frame()->page()) {
157 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
158 scrollingCoordinator->willDestroyRenderLayer(this);
161 removeFilterInfoIfNeeded();
163 if (groupedMapping()) {
164 DisableCompositingQueryAsserts disabler;
165 groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this);
166 setGroupedMapping(0);
169 // Child layers will be deleted by their corresponding render objects, so
170 // we don't need to delete them ourselves.
172 clearCompositedLayerMapping(true);
174 if (m_reflectionInfo)
175 m_reflectionInfo->destroy();
178 String RenderLayer::debugName() const
180 if (isReflection()) {
181 return renderer()->parent()->debugName() + " (reflection)";
183 return renderer()->debugName();
186 RenderLayerCompositor* RenderLayer::compositor() const
188 if (!renderer()->view())
190 return renderer()->view()->compositor();
193 void RenderLayer::contentChanged(ContentChangeType changeType)
195 // updateLayerCompositingState will query compositingReasons for accelerated overflow scrolling.
196 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html
197 DisableCompositingQueryAsserts disabler;
199 if (changeType == CanvasChanged)
200 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
202 if (changeType == CanvasContextChanged) {
203 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
205 // Although we're missing test coverage, we need to call
206 // GraphicsLayer::setContentsToPlatformLayer with the new platform
207 // layer for this canvas.
208 // See http://crbug.com/349195
209 if (hasCompositedLayerMapping())
210 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
213 if (m_compositedLayerMapping)
214 m_compositedLayerMapping->contentChanged(changeType);
217 bool RenderLayer::paintsWithFilters() const
219 if (!renderer()->hasFilter())
222 // https://code.google.com/p/chromium/issues/detail?id=343759
223 DisableCompositingQueryAsserts disabler;
224 return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacking;
227 LayoutSize RenderLayer::subpixelAccumulation() const
229 return m_subpixelAccumulation;
232 void RenderLayer::setSubpixelAccumulation(const LayoutSize& size)
234 m_subpixelAccumulation = size;
237 void RenderLayer::updateLayerPositionsAfterLayout()
239 TRACE_EVENT0("blink", "RenderLayer::updateLayerPositionsAfterLayout");
241 m_clipper.clearClipRectsIncludingDescendants();
242 updateLayerPositionRecursive();
245 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
246 // https://code.google.com/p/chromium/issues/detail?id=343756
247 DisableCompositingQueryAsserts disabler;
248 bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer();
249 updatePaginationRecursive(needsPaginationUpdate);
253 void RenderLayer::updateLayerPositionRecursive()
255 if (m_reflectionInfo)
256 m_reflectionInfo->reflection()->layout();
258 // FIXME: We should be able to remove this call because we don't care about
259 // any descendant-dependent flags, but code somewhere else is reading these
260 // flags and depending on us to update them.
261 updateDescendantDependentFlags();
263 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
264 child->updateLayerPositionRecursive();
267 void RenderLayer::updateHasSelfPaintingLayerDescendant() const
269 ASSERT(m_hasSelfPaintingLayerDescendantDirty);
271 m_hasSelfPaintingLayerDescendant = false;
273 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
274 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) {
275 m_hasSelfPaintingLayerDescendant = true;
280 m_hasSelfPaintingLayerDescendantDirty = false;
283 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
285 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
286 layer->m_hasSelfPaintingLayerDescendantDirty = true;
287 // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
288 // in this case, there is no need to dirty our ancestors further.
289 if (layer->isSelfPaintingLayer()) {
290 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->m_hasSelfPaintingLayerDescendant);
296 bool RenderLayer::scrollsWithViewport() const
298 return renderer()->style()->position() == FixedPosition && renderer()->containerForFixedPosition() == renderer()->view();
301 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
303 if (scrollsWithViewport() != other->scrollsWithViewport())
305 return ancestorScrollingLayer() != other->ancestorScrollingLayer();
308 void RenderLayer::updateTransformationMatrix()
311 RenderBox* box = renderBox();
313 m_transform->makeIdentity();
314 box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
315 makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositing());
319 void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle)
321 if (oldStyle && newStyle->transformDataEquivalent(*oldStyle))
324 // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
325 // so check style too.
326 bool hasTransform = renderer()->hasTransform() && newStyle->hasTransform();
327 bool had3DTransform = has3DTransform();
329 bool hadTransform = m_transform;
330 if (hasTransform != hadTransform) {
332 m_transform = adoptPtr(new TransformationMatrix);
336 // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
337 m_clipper.clearClipRectsIncludingDescendants();
338 } else if (hasTransform) {
339 m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
342 updateTransformationMatrix();
344 if (had3DTransform != has3DTransform())
345 dirty3DTransformedDescendantStatus();
348 static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer)
350 if (RenderObject* containingBlock = layer->renderer()->containingBlock())
351 return containingBlock->enclosingLayer();
355 RenderLayer* RenderLayer::renderingContextRoot()
357 RenderLayer* renderingContext = 0;
359 if (shouldPreserve3D())
360 renderingContext = this;
362 for (RenderLayer* current = enclosingLayerForContainingBlock(this); current && current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current))
363 renderingContext = current;
365 return renderingContext;
368 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
371 return TransformationMatrix();
373 // m_transform includes transform-origin, so we need to recompute the transform here.
374 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
375 RenderBox* box = renderBox();
376 TransformationMatrix currTransform;
377 box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
378 makeMatrixRenderable(currTransform, compositor()->hasAcceleratedCompositing());
379 return currTransform;
385 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
388 return TransformationMatrix();
390 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
391 TransformationMatrix matrix = *m_transform;
392 makeMatrixRenderable(matrix, false /* flatten 3d */);
399 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
401 const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
403 if (layer->renderer()->hasOverflowClip())
404 return const_cast<RenderLayer*>(layer);
406 layer = layer->parent();
411 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
413 RenderView* view = renderer->view();
414 RenderLayerModelObject* prevBlock = renderer;
415 RenderBlock* containingBlock;
416 for (containingBlock = renderer->containingBlock();
417 containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
418 containingBlock = containingBlock->containingBlock())
419 prevBlock = containingBlock;
421 // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
422 if (containingBlock != ancestorColumnsRenderer)
425 // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
426 if (prevBlock->isOutOfFlowPositioned())
429 // Otherwise we are paginated by the columns block.
433 bool RenderLayer::useRegionBasedColumns() const
435 return renderer()->document().regionBasedColumnsEnabled();
438 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate)
440 m_isPaginated = false;
441 m_enclosingPaginationLayer = 0;
443 if (useRegionBasedColumns() && renderer()->isRenderFlowThread())
444 needsPaginationUpdate = true;
446 if (needsPaginationUpdate)
449 if (renderer()->hasColumns())
450 needsPaginationUpdate = true;
452 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
453 child->updatePaginationRecursive(needsPaginationUpdate);
456 void RenderLayer::updatePagination()
458 if (compositingState() != NotComposited || !parent())
459 return; // FIXME: We will have to deal with paginated compositing layers someday.
460 // FIXME: For now the RenderView can't be paginated. Eventually printing will move to a model where it is though.
462 // The main difference between the paginated booleans for the old column code and the new column code
463 // is that each paginated layer has to paint on its own with the new code. There is no
464 // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on
465 // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and
466 // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
467 // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
468 // to that layer easily.
469 bool regionBasedColumnsUsed = useRegionBasedColumns();
470 if (regionBasedColumnsUsed && renderer()->isRenderFlowThread()) {
471 m_enclosingPaginationLayer = this;
475 if (m_stackingNode->isNormalFlowOnly()) {
476 if (regionBasedColumnsUsed) {
477 // Content inside a transform is not considered to be paginated, since we simply
478 // paint the transform multiple times in each column, so we don't have to use
479 // fragments for the transformed content.
480 m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
481 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
482 m_enclosingPaginationLayer = 0;
484 m_isPaginated = parent()->renderer()->hasColumns();
489 // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
490 // we find one, then we just check its pagination status.
491 if (regionBasedColumnsUsed) {
492 RenderView* view = renderer()->view();
493 RenderBlock* containingBlock;
494 for (containingBlock = renderer()->containingBlock();
495 containingBlock && containingBlock != view;
496 containingBlock = containingBlock->containingBlock()) {
497 if (containingBlock->hasLayer()) {
498 // Content inside a transform is not considered to be paginated, since we simply
499 // paint the transform multiple times in each column, so we don't have to use
500 // fragments for the transformed content.
501 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer();
502 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
503 m_enclosingPaginationLayer = 0;
510 // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
511 RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorStackingContextNode();
512 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
513 if (curr->renderer()->hasColumns()) {
514 m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
517 if (curr->stackingNode() == ancestorStackingContextNode)
522 LayoutPoint RenderLayer::positionFromPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
524 FloatPoint point = renderObject->localToContainerPoint(FloatPoint(), paintInvalidationContainer, 0, 0, paintInvalidationState);
526 // FIXME: Eventually we are going to unify coordinates in GraphicsLayer space.
527 if (paintInvalidationContainer && paintInvalidationContainer->layer()->groupedMapping())
528 mapPointToPaintBackingCoordinates(paintInvalidationContainer, point);
530 return LayoutPoint(point);
533 void RenderLayer::mapPointToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, FloatPoint& point)
535 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
536 if (!paintInvalidationLayer->groupedMapping()) {
537 point.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
541 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
542 if (!transformedAncestor)
545 // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
546 // transformed ancestor.
547 point = paintInvalidationContainer->localToContainerPoint(point, transformedAncestor);
549 point.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
552 void RenderLayer::mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect)
554 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
555 if (!paintInvalidationLayer->groupedMapping()) {
556 rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
560 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
561 if (!transformedAncestor)
564 // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
565 // transformed ancestor.
566 rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect(rect), transformedAncestor).boundingBox());
568 rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
571 void RenderLayer::mapRectToPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState)
573 if (!paintInvalidationContainer->layer()->groupedMapping()) {
574 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
578 // This code adjusts the paint invalidation rectangle to be in the space of the transformed ancestor of the grouped (i.e. squashed)
579 // layer. This is because all layers that squash together need to issue paint invalidations w.r.t. a single container that is
580 // an ancestor of all of them, in order to properly take into account any local transforms etc.
581 // FIXME: remove this special-case code that works around the paint invalidation code structure.
582 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
584 mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect);
587 LayoutRect RenderLayer::computePaintInvalidationRect(const RenderObject* renderObject, const RenderLayer* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
589 if (!paintInvalidationContainer->groupedMapping())
590 return renderObject->computePaintInvalidationRect(paintInvalidationContainer->renderer(), paintInvalidationState);
592 LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer->renderer(), paintInvalidationState);
593 mapRectToPaintBackingCoordinates(paintInvalidationContainer->renderer(), rect);
597 void RenderLayer::dirtyVisibleContentStatus()
599 m_visibleContentStatusDirty = true;
601 parent()->dirtyAncestorChainVisibleDescendantStatus();
604 void RenderLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility)
606 if (m_visibleContentStatusDirty)
608 if (hasVisibleContent() == (visibility == VISIBLE))
610 dirtyVisibleContentStatus();
613 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
615 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
616 if (layer->m_visibleDescendantStatusDirty)
619 layer->m_visibleDescendantStatusDirty = true;
623 // FIXME: this is quite brute-force. We could be more efficient if we were to
624 // track state and update it as appropriate as changes are made in the Render tree.
625 void RenderLayer::updateScrollingStateAfterCompositingChange()
627 TRACE_EVENT0("blink", "RenderLayer::updateScrollingStateAfterCompositingChange");
628 m_hasVisibleNonLayerContent = false;
629 for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()) {
630 if (!r->hasLayer()) {
631 m_hasVisibleNonLayerContent = true;
636 m_hasNonCompositedChild = false;
637 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
638 if (child->compositingState() == NotComposited || child->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
639 m_hasNonCompositedChild = true;
645 // The descendant-dependent flags system is badly broken because we clean dirty
646 // bits in upward tree walks, which means we need to call updateDescendantDependentFlags
647 // at every node in the tree to fully clean all the dirty bits. While we'll in
648 // the process of fixing this issue, updateDescendantDependentFlagsForEntireSubtree
649 // provides a big hammer for actually cleaning all the dirty bits in a subtree.
651 // FIXME: Remove this function once the descendant-dependent flags system keeps
652 // its dirty bits scoped to subtrees.
653 void RenderLayer::updateDescendantDependentFlagsForEntireSubtree()
655 updateDescendantDependentFlags();
657 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
658 child->updateDescendantDependentFlagsForEntireSubtree();
661 void RenderLayer::updateDescendantDependentFlags()
663 if (m_visibleDescendantStatusDirty) {
664 m_hasVisibleDescendant = false;
666 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
667 child->updateDescendantDependentFlags();
669 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
670 m_hasVisibleDescendant = true;
675 m_visibleDescendantStatusDirty = false;
678 if (m_visibleContentStatusDirty) {
679 bool previouslyHasVisibleContent = m_hasVisibleContent;
680 if (renderer()->style()->visibility() == VISIBLE)
681 m_hasVisibleContent = true;
683 // layer may be hidden but still have some visible content, check for this
684 m_hasVisibleContent = false;
685 RenderObject* r = renderer()->slowFirstChild();
687 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
688 m_hasVisibleContent = true;
691 RenderObject* rendererFirstChild = r->slowFirstChild();
692 if (rendererFirstChild && !r->hasLayer())
693 r = rendererFirstChild;
694 else if (r->nextSibling())
695 r = r->nextSibling();
701 } while (r && !r->nextSibling());
703 r = r->nextSibling();
707 m_visibleContentStatusDirty = false;
709 if (hasVisibleContent() != previouslyHasVisibleContent) {
710 setNeedsCompositingInputsUpdate();
711 // We need to tell m_renderer to recheck its rect because we
712 // pretend that invisible RenderObjects have 0x0 rects. Changing
713 // visibility therefore changes our rect and we need to visit
714 // this RenderObject during the invalidateTreeIfNeeded walk.
715 m_renderer->setMayNeedPaintInvalidation(true);
720 void RenderLayer::dirty3DTransformedDescendantStatus()
722 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNode();
726 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
728 // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
729 // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
730 while (stackingNode && stackingNode->layer()->preserves3D()) {
731 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
732 stackingNode = stackingNode->ancestorStackingContextNode();
736 // Return true if this layer or any preserve-3d descendants have 3d.
737 bool RenderLayer::update3DTransformedDescendantStatus()
739 if (m_3DTransformedDescendantStatusDirty) {
740 m_has3DTransformedDescendant = false;
742 m_stackingNode->updateZOrderLists();
744 // Transformed or preserve-3d descendants can only be in the z-order lists, not
745 // in the normal flow list, so we only need to check those.
746 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren);
747 while (RenderLayerStackingNode* node = iterator.next())
748 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDescendantStatus();
750 m_3DTransformedDescendantStatusDirty = false;
753 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
754 // the m_has3DTransformedDescendant set.
756 return has3DTransform() || m_has3DTransformedDescendant;
758 return has3DTransform();
761 IntSize RenderLayer::size() const
763 if (renderer()->isInline() && renderer()->isRenderInline())
764 return toRenderInline(renderer())->linesBoundingBox().size();
766 // FIXME: Is snapping the size really needed here?
767 if (RenderBox* box = renderBox())
768 return pixelSnappedIntSize(box->size(), box->location());
773 LayoutPoint RenderLayer::location() const
775 LayoutPoint localPoint;
776 LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
778 if (renderer()->isInline() && renderer()->isRenderInline()) {
779 RenderInline* inlineFlow = toRenderInline(renderer());
780 IntRect lineBox = inlineFlow->linesBoundingBox();
781 inlineBoundingBoxOffset = toSize(lineBox.location());
782 localPoint += inlineBoundingBoxOffset;
783 } else if (RenderBox* box = renderBox()) {
784 localPoint += box->topLeftLocationOffset();
787 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) {
788 // We must adjust our position by walking up the render tree looking for the
789 // nearest enclosing object with a layer.
790 RenderObject* curr = renderer()->parent();
791 while (curr && !curr->hasLayer()) {
792 if (curr->isBox() && !curr->isTableRow()) {
793 // Rows and cells share the same coordinate space (that of the section).
794 // Omit them when computing our xpos/ypos.
795 localPoint += toRenderBox(curr)->topLeftLocationOffset();
797 curr = curr->parent();
799 if (curr->isBox() && curr->isTableRow()) {
800 // Put ourselves into the row coordinate space.
801 localPoint -= toRenderBox(curr)->topLeftLocationOffset();
805 // Subtract our parent's scroll offset.
806 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
807 RenderLayer* positionedParent = enclosingPositionedAncestor();
809 // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
810 if (positionedParent->renderer()->hasOverflowClip()) {
811 LayoutSize offset = positionedParent->renderBox()->scrolledContentOffset();
812 localPoint -= offset;
815 if (positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
816 LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer()));
817 localPoint += offset;
819 } else if (parent()) {
820 // FIXME: This code is very wrong. The compositing system doesn't
821 // understand columns and we're hacking around that fact by faking
822 // the position of the RenderLayers when we think we'll end up being
823 // composited. Hopefully we'll be able to unwind this hack when we
824 // implement multi-column using regions.
825 if (hasStyleDeterminedDirectCompositingReasons()) {
826 // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
827 // They won't split across columns properly.
828 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isDocumentElement() && renderer()->view()->hasColumns())
829 localPoint += renderer()->view()->columnOffset(localPoint);
831 localPoint += parent()->renderer()->columnOffset(localPoint);
834 if (parent()->renderer()->hasOverflowClip()) {
835 IntSize scrollOffset = parent()->renderBox()->scrolledContentOffset();
836 localPoint -= scrollOffset;
840 localPoint.move(offsetForInFlowPosition());
842 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
843 localPoint -= inlineBoundingBoxOffset;
848 const LayoutSize RenderLayer::offsetForInFlowPosition() const
850 return renderer()->isRelPositioned() ? toRenderBoxModelObject(renderer())->offsetForInFlowPosition() : LayoutSize();
853 TransformationMatrix RenderLayer::perspectiveTransform() const
855 if (!renderer()->hasTransform())
856 return TransformationMatrix();
858 RenderStyle* style = renderer()->style();
859 if (!style->hasPerspective())
860 return TransformationMatrix();
862 // Maybe fetch the perspective from the backing?
863 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
864 const float boxWidth = borderBox.width();
865 const float boxHeight = borderBox.height();
867 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth);
868 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight);
870 // A perspective origin of 0,0 makes the vanishing point in the center of the element.
871 // We want it to be in the top-left, so subtract half the height and width.
872 perspectiveOriginX -= boxWidth / 2.0f;
873 perspectiveOriginY -= boxHeight / 2.0f;
875 TransformationMatrix t;
876 t.translate(perspectiveOriginX, perspectiveOriginY);
877 t.applyPerspective(style->perspective());
878 t.translate(-perspectiveOriginX, -perspectiveOriginY);
883 FloatPoint RenderLayer::perspectiveOrigin() const
885 if (!renderer()->hasTransform())
888 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
889 RenderStyle* style = renderer()->style();
891 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.height().toFloat()));
894 static inline bool isFixedPositionedContainer(RenderLayer* layer)
896 return layer->isRootLayer() || layer->hasTransform();
899 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
901 RenderLayer* curr = parent();
902 while (curr && !curr->isPositionedContainer())
903 curr = curr->parent();
908 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
910 RenderLayer* curr = parent();
911 while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransform())
912 curr = curr->parent();
917 LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const
919 const AncestorDependentCompositingInputs& properties = ancestorDependentCompositingInputs();
921 TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
922 // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip are correct.
923 renderer()->mapLocalToContainer(properties.transformAncestor ? properties.transformAncestor->renderer() : 0, transformState, ApplyContainerFlip);
924 transformState.flatten();
925 return LayoutPoint(transformState.lastPlanarPoint());
928 const RenderLayer* RenderLayer::compositingContainer() const
930 if (stackingNode()->isNormalFlowOnly())
932 if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContextNode())
933 return ancestorStackingNode->layer();
937 bool RenderLayer::isPaintInvalidationContainer() const
939 return compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking;
942 // Note: enclosingCompositingLayer does not include squashed layers. Compositing stacking children of squashed layers
943 // receive graphics layers that are parented to the compositing ancestor of the squashed layer.
944 RenderLayer* RenderLayer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot includeSelf) const
946 ASSERT(isAllowedToQueryCompositingState());
948 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
949 return const_cast<RenderLayer*>(this);
951 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
952 if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking)
953 return const_cast<RenderLayer*>(curr);
959 // Return the enclosingCompositedLayerForPaintInvalidation for the given RenderLayer
960 // including crossing frame boundaries.
961 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const
963 const RenderLayer* layer = this;
964 RenderLayer* compositedLayer = 0;
965 while (!compositedLayer) {
966 compositedLayer = layer->enclosingLayerForPaintInvalidation();
967 if (!compositedLayer) {
968 RenderObject* owner = layer->renderer()->frame()->ownerRenderer();
971 layer = owner->enclosingLayer();
974 return compositedLayer;
977 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidation() const
979 ASSERT(isAllowedToQueryCompositingState());
981 if (isPaintInvalidationContainer())
982 return const_cast<RenderLayer*>(this);
984 for (const RenderLayer* curr = parent(); curr; curr = curr->parent()) {
985 if (curr->isPaintInvalidationContainer())
986 return const_cast<RenderLayer*>(curr);
992 void RenderLayer::setNeedsCompositingInputsUpdate()
994 m_needsAncestorDependentCompositingInputsUpdate = true;
995 m_needsDescendantDependentCompositingInputsUpdate = true;
997 for (RenderLayer* current = this; current && !current->m_childNeedsCompositingInputsUpdate; current = current->parent())
998 current->m_childNeedsCompositingInputsUpdate = true;
1000 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
1003 void RenderLayer::updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs& compositingInputs)
1005 m_ancestorDependentCompositingInputs = compositingInputs;
1006 m_needsAncestorDependentCompositingInputsUpdate = false;
1009 void RenderLayer::updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs& compositingInputs)
1011 m_descendantDependentCompositingInputs = compositingInputs;
1012 m_needsDescendantDependentCompositingInputsUpdate = false;
1015 void RenderLayer::didUpdateCompositingInputs()
1017 ASSERT(!needsCompositingInputsUpdate());
1018 m_childNeedsCompositingInputsUpdate = false;
1019 if (m_scrollableArea)
1020 m_scrollableArea->updateNeedsCompositedScrolling();
1023 void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingReasons mask)
1025 if ((compositingReasons() & mask) == (reasons & mask))
1027 m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask);
1030 void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant)
1032 if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescendant))
1035 m_hasCompositingDescendant = hasCompositingDescendant;
1037 if (hasCompositedLayerMapping())
1038 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
1041 void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDescendants)
1043 if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsolateCompositedDescendants))
1046 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants;
1048 if (hasCompositedLayerMapping())
1049 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
1052 bool RenderLayer::hasAncestorWithFilterOutsets() const
1054 for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1055 RenderLayerModelObject* renderer = curr->renderer();
1056 if (renderer->style()->hasFilterOutsets())
1062 RenderLayer* RenderLayer::transparentPaintingAncestor()
1064 if (hasCompositedLayerMapping())
1067 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1068 if (curr->hasCompositedLayerMapping())
1070 if (curr->isTransparent())
1076 enum TransparencyClipBoxBehavior {
1077 PaintingTransparencyClipBox,
1078 HitTestingTransparencyClipBox
1081 enum TransparencyClipBoxMode {
1082 DescendantsOfTransparencyClipBox,
1083 RootOfTransparencyClipBox
1086 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0);
1088 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1089 TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1091 // If we have a mask, then the clip is limited to the border box area (and there is
1092 // no need to examine child layers).
1093 if (!layer->renderer()->hasMask()) {
1094 // Note: we don't have to walk z-order lists since transparent elements always establish
1095 // a stacking container. This means we can just walk the layer tree directly.
1096 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1097 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
1098 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior));
1102 // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire
1103 // current transparencyClipBox to catch all child layers.
1104 // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1105 // size into the parent layer.
1106 if (layer->renderer()->hasReflection()) {
1108 layer->convertToLayerCoords(rootLayer, delta);
1109 clipRect.move(-delta.x(), -delta.y());
1110 clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1111 clipRect.moveBy(delta);
1115 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1116 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1118 // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1119 // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
1120 // would be better to respect clips.
1122 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
1123 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) {
1124 // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1125 // the transformed layer and all of its children.
1126 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
1127 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1129 layer->convertToLayerCoords(rootLayerForTransform, delta);
1131 delta.move(subPixelAccumulation);
1132 IntPoint pixelSnappedDelta = roundedIntPoint(delta);
1133 TransformationMatrix transform;
1134 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
1135 transform = transform * *layer->transform();
1137 // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1138 // paints unfragmented.
1139 LayoutRect clipRect = layer->physicalBoundingBox(layer);
1140 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior);
1141 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1142 LayoutRect result = transform.mapRect(clipRect);
1143 if (!paginationLayer)
1146 // We have to break up the transformed extent across our columns.
1147 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1148 // get our true bounding box.
1149 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1150 result = enclosingFlowThread->fragmentsBoundingBox(result);
1152 LayoutPoint rootLayerDelta;
1153 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1154 result.moveBy(rootLayerDelta);
1158 LayoutRect clipRect = layer->physicalBoundingBox(rootLayer);
1159 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior);
1160 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1161 clipRect.move(subPixelAccumulation);
1165 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1167 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect);
1170 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1172 bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && hasDescendantWithBlendMode();
1173 if ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency)
1176 RenderLayer* ancestor = transparentPaintingAncestor();
1178 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
1180 if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) {
1181 m_usedTransparency = true;
1183 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
1184 context->clip(clipRect);
1186 if (paintsWithBlendMode())
1187 context->setCompositeOperation(context->compositeOperation(), m_renderer->style()->blendMode());
1189 context->beginTransparencyLayer(renderer()->opacity());
1191 if (paintsWithBlendMode())
1192 context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal);
1193 #ifdef REVEAL_TRANSPARENCY_LAYERS
1194 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
1195 context->fillRect(clipRect);
1200 void* RenderLayer::operator new(size_t sz)
1202 return partitionAlloc(Partitions::getRenderingPartition(), sz);
1205 void RenderLayer::operator delete(void* ptr)
1210 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1212 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1214 child->setPreviousSibling(prevSibling);
1215 prevSibling->setNextSibling(child);
1216 ASSERT(prevSibling != child);
1218 setFirstChild(child);
1221 beforeChild->setPreviousSibling(child);
1222 child->setNextSibling(beforeChild);
1223 ASSERT(beforeChild != child);
1225 setLastChild(child);
1227 child->m_parent = this;
1229 setNeedsCompositingInputsUpdate();
1231 if (child->stackingNode()->isNormalFlowOnly())
1232 m_stackingNode->dirtyNormalFlowList();
1234 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) {
1235 // Dirty the z-order list in which we are contained. The ancestorStackingContextNode() can be null in the
1236 // case where we're building up generated content layers. This is ok, since the lists will start
1237 // off dirty in that case anyway.
1238 child->stackingNode()->dirtyStackingContextZOrderLists();
1241 dirtyAncestorChainVisibleDescendantStatus();
1242 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1244 child->updateDescendantDependentFlags();
1247 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1249 if (oldChild->previousSibling())
1250 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1251 if (oldChild->nextSibling())
1252 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1254 if (m_first == oldChild)
1255 m_first = oldChild->nextSibling();
1256 if (m_last == oldChild)
1257 m_last = oldChild->previousSibling();
1259 if (oldChild->stackingNode()->isNormalFlowOnly())
1260 m_stackingNode->dirtyNormalFlowList();
1261 if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) {
1262 // Dirty the z-order list in which we are contained. When called via the
1263 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1264 // from the main layer tree, so we need to null-check the
1265 // |stackingContext| value.
1266 oldChild->stackingNode()->dirtyStackingContextZOrderLists();
1269 if (renderer()->style()->visibility() != VISIBLE)
1270 dirtyVisibleContentStatus();
1272 oldChild->setPreviousSibling(0);
1273 oldChild->setNextSibling(0);
1274 oldChild->m_parent = 0;
1276 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1278 oldChild->updateDescendantDependentFlags();
1280 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1281 dirtyAncestorChainVisibleDescendantStatus();
1286 void RenderLayer::removeOnlyThisLayer()
1291 m_clipper.clearClipRectsIncludingDescendants();
1293 RenderLayer* nextSib = nextSibling();
1295 // Remove the child reflection layer before moving other child layers.
1296 // The reflection layer should not be moved to the parent.
1297 if (m_reflectionInfo)
1298 removeChild(m_reflectionInfo->reflectionLayer());
1300 // Now walk our kids and reattach them to our parent.
1301 RenderLayer* current = m_first;
1303 RenderLayer* next = current->nextSibling();
1304 removeChild(current);
1305 m_parent->addChild(current, nextSib);
1307 // FIXME: We should call a specialized version of this function.
1308 current->updateLayerPositionsAfterLayout();
1312 // Remove us from the parent.
1313 m_parent->removeChild(this);
1314 m_renderer->destroyLayer();
1317 void RenderLayer::insertOnlyThisLayer()
1319 if (!m_parent && renderer()->parent()) {
1320 // We need to connect ourselves when our renderer() has a parent.
1321 // Find our enclosingLayer and add ourselves.
1322 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
1323 ASSERT(parentLayer);
1324 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
1325 parentLayer->addChild(this, beforeChild);
1328 // Remove all descendant layers from the hierarchy and add them to the new position.
1329 for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->nextSibling())
1330 curr->moveLayers(m_parent, this);
1332 // Clear out all the clip rects.
1333 m_clipper.clearClipRectsIncludingDescendants();
1336 // Returns the layer reached on the walk up towards the ancestor.
1337 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
1339 ASSERT(ancestorLayer != layer);
1341 const RenderLayerModelObject* renderer = layer->renderer();
1342 EPosition position = renderer->style()->position();
1344 // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great.
1345 RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer->flowThreadContainingBlock() : 0;
1346 if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
1347 fixedFlowThreadContainer = 0;
1349 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1350 // may need to be revisited in a future patch.
1351 // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1352 // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be
1353 // positioned in a completely different place in the viewport (RenderView).
1354 if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
1355 // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1356 // localToAbsolute() on the RenderView.
1357 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed);
1358 location += LayoutSize(absPos.x(), absPos.y());
1359 return ancestorLayer;
1362 // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1363 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1364 // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1365 if (position == FixedPosition && !fixedFlowThreadContainer) {
1366 // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1367 // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1368 // so we should always find the ancestor at or before we find the fixed position container.
1369 RenderLayer* fixedPositionContainerLayer = 0;
1370 bool foundAncestor = false;
1371 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1372 if (currLayer == ancestorLayer)
1373 foundAncestor = true;
1375 if (isFixedPositionedContainer(currLayer)) {
1376 fixedPositionContainerLayer = currLayer;
1377 ASSERT_UNUSED(foundAncestor, foundAncestor);
1382 ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1384 if (fixedPositionContainerLayer != ancestorLayer) {
1385 LayoutPoint fixedContainerCoords;
1386 layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1388 LayoutPoint ancestorCoords;
1389 ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1391 location += (fixedContainerCoords - ancestorCoords);
1393 location += toSize(layer->location());
1395 return ancestorLayer;
1398 RenderLayer* parentLayer;
1399 if (position == AbsolutePosition || position == FixedPosition) {
1400 // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
1401 parentLayer = layer->parent();
1402 bool foundAncestorFirst = false;
1403 while (parentLayer) {
1404 // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
1405 // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
1406 // we are bailing out before reaching root layer.
1407 if (parentLayer->isPositionedContainer())
1410 if (parentLayer == ancestorLayer) {
1411 foundAncestorFirst = true;
1415 parentLayer = parentLayer->parent();
1418 // We should not reach RenderView layer past the RenderFlowThread layer for any
1419 // children of the RenderFlowThread.
1420 ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer());
1422 if (foundAncestorFirst) {
1423 // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
1424 // to enclosingPositionedAncestor and subtract.
1425 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
1427 LayoutPoint thisCoords;
1428 layer->convertToLayerCoords(positionedAncestor, thisCoords);
1430 LayoutPoint ancestorCoords;
1431 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
1433 location += (thisCoords - ancestorCoords);
1434 return ancestorLayer;
1437 parentLayer = layer->parent();
1442 location += toSize(layer->location());
1446 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
1448 if (ancestorLayer == this)
1451 const RenderLayer* currLayer = this;
1452 while (currLayer && currLayer != ancestorLayer)
1453 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location);
1456 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
1459 convertToLayerCoords(ancestorLayer, delta);
1460 rect.move(-delta.x(), -delta.y());
1463 void RenderLayer::didUpdateNeedsCompositedScrolling()
1465 updateSelfPaintingLayer();
1468 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle)
1470 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle));
1471 if (renderer()->hasReflection()) {
1472 if (!m_reflectionInfo)
1473 m_reflectionInfo = adoptPtrWillBeNoop(new RenderLayerReflectionInfo(*renderBox()));
1474 m_reflectionInfo->updateAfterStyleChange(oldStyle);
1475 } else if (m_reflectionInfo) {
1476 m_reflectionInfo->destroy();
1477 m_reflectionInfo = nullptr;
1481 void RenderLayer::updateStackingNode()
1483 if (requiresStackingNode())
1484 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this));
1486 m_stackingNode = nullptr;
1489 void RenderLayer::updateScrollableArea()
1491 if (requiresScrollableArea())
1492 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this));
1494 m_scrollableArea = nullptr;
1497 bool RenderLayer::hasOverflowControls() const
1499 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE);
1502 void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, PaintLayerFlags paintFlags)
1504 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
1505 if (shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags))
1506 paintLayer(context, paintingInfo, paintFlags);
1509 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
1511 if (!m_containsDirtyOverlayScrollbars)
1514 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
1515 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars);
1517 m_containsDirtyOverlayScrollbars = false;
1520 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
1522 if (startLayer == endLayer)
1525 RenderView* view = startLayer->renderer()->view();
1526 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) {
1527 if (currentBlock->layer() == endLayer)
1534 void RenderLayer::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect,
1535 PaintLayerFlags paintFlags, BorderRadiusClippingRule rule)
1537 if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius())
1540 context->clip(pixelSnappedIntRect(clipRect.rect()));
1542 if (!clipRect.hasRadius())
1545 // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
1546 // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
1547 // containing block chain so we check that also.
1548 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
1549 // Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not
1550 // want to apply a border-radius clip to the layer contents itself, because that would require re-rastering
1551 // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
1552 // that it can in turn clip the scrolled contents in the compositor.
1553 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
1556 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
1558 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
1559 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
1562 if (layer == localPaintingInfo.rootLayer)
1567 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
1569 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
1574 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
1576 // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
1577 // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
1578 // will do a full paintInvalidationForWholeRenderer().
1579 if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isDocumentElement())
1585 static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags)
1587 return layer->renderer()->isDocumentElement() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
1590 static ShouldRespectOverflowClip shouldRespectOverflowClip(PaintLayerFlags paintFlags, const RenderObject* renderer)
1592 return (paintFlags & PaintLayerPaintingOverflowContents || (paintFlags & PaintLayerPaintingChildClippingMaskPhase && renderer->hasClipPath())) ? IgnoreOverflowClip : RespectOverflowClip;
1595 void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1597 // https://code.google.com/p/chromium/issues/detail?id=343772
1598 DisableCompositingQueryAsserts disabler;
1600 if (compositingState() != NotComposited) {
1601 if (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers) {
1602 // FIXME: ok, but what about PaintBehaviorFlattenCompositingLayers? That's for printing.
1603 // FIXME: why isn't the code here global, as opposed to being set on each paintLayer() call?
1604 paintFlags |= PaintLayerUncachedClipRects;
1608 // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
1609 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
1612 if (shouldSuppressPaintingLayer(this))
1615 // If this layer is totally invisible then there is nothing to paint.
1616 if (!renderer()->opacity())
1619 if (paintsWithTransparency(paintingInfo.paintBehavior))
1620 paintFlags |= PaintLayerHaveTransparency;
1622 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice.
1623 if (paintsWithTransform(paintingInfo.paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
1624 TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior);
1625 // If the transform can't be inverted, then don't paint anything.
1626 if (!layerTransform.isInvertible())
1629 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
1630 // layer from the parent now, assuming there is a parent
1631 if (paintFlags & PaintLayerHaveTransparency) {
1633 parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
1635 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
1638 if (enclosingPaginationLayer()) {
1639 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags);
1643 // Make sure the parent's clip rects have been calculated.
1644 ClipRect clipRect = paintingInfo.paintDirtyRect;
1646 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize);
1647 if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip)
1648 clipRectsContext.setIgnoreOverflowClip();
1649 clipRect = clipper().backgroundClipRect(clipRectsContext);
1650 clipRect.intersect(paintingInfo.paintDirtyRect);
1652 // Push the parent coordinate space's clip.
1653 parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
1656 paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
1658 // Restore the clip.
1660 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
1665 paintLayerContentsAndReflection(context, paintingInfo, paintFlags);
1668 void RenderLayer::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1670 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1672 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
1674 // Paint the reflection first if we have one.
1675 if (m_reflectionInfo)
1676 m_reflectionInfo->paint(context, paintingInfo, localPaintFlags | PaintLayerPaintingReflection);
1678 localPaintFlags |= PaintLayerPaintingCompositingAllPhases;
1679 paintLayerContents(context, paintingInfo, localPaintFlags);
1682 void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1684 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1685 ASSERT(!(paintFlags & PaintLayerAppliedTransform));
1687 bool haveTransparency = paintFlags & PaintLayerHaveTransparency;
1688 bool isSelfPaintingLayer = this->isSelfPaintingLayer();
1689 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
1690 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase;
1691 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase;
1692 bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase;
1693 bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents;
1694 // Outline always needs to be painted even if we have no visible content. Also,
1695 // the outline is painted in the background phase during composited scrolling.
1696 // If it were painted in the foreground phase, it would move with the scrolled
1697 // content. When not composited scrolling, the outline is painted in the
1698 // foreground phase. Since scrolled contents are moved by paint invalidation in this
1699 // case, the outline won't get 'dragged along'.
1700 bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
1701 && ((isPaintingScrollingContent && isPaintingCompositedBackground)
1702 || (!isPaintingScrollingContent && isPaintingCompositedForeground));
1703 bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
1705 float deviceScaleFactor = blink::deviceScaleFactor(renderer()->frame());
1706 context->setDeviceScaleFactor(deviceScaleFactor);
1708 GraphicsContext* transparencyLayerContext = context;
1710 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isDocumentElement())
1713 // Ensure our lists are up-to-date.
1714 m_stackingNode->updateLayerListsIfNeeded();
1716 LayoutPoint offsetFromRoot;
1717 convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
1719 if (compositingState() == PaintsIntoOwnBacking)
1720 offsetFromRoot.move(subpixelAccumulation());
1722 LayoutRect rootRelativeBounds;
1723 bool rootRelativeBoundsComputed = false;
1725 // Apply clip-path to context.
1726 GraphicsContextStateSaver clipStateSaver(*context, false);
1727 RenderStyle* style = renderer()->style();
1728 RenderSVGResourceClipper* resourceClipper = 0;
1729 RenderSVGResourceClipper::ClipperState clipperState = RenderSVGResourceClipper::ClipperNotApplied;
1731 // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container.
1732 // It must, however, still be applied to the mask layer, so that the compositor can properly mask the
1733 // scrolling contents and scrollbars.
1734 if (renderer()->hasClipPath() && style && (!needsCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase)) {
1735 ASSERT(style->clipPath());
1736 if (style->clipPath()->type() == ClipPathOperation::SHAPE) {
1737 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath());
1738 if (clipPath->isValid()) {
1739 clipStateSaver.save();
1741 if (!rootRelativeBoundsComputed) {
1742 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1743 rootRelativeBoundsComputed = true;
1746 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule());
1748 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) {
1749 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath());
1750 Document& document = renderer()->document();
1751 // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
1752 Element* element = document.getElementById(referenceClipPathOperation->fragment());
1753 if (isSVGClipPathElement(element) && element->renderer()) {
1754 // FIXME: Saving at this point is not required in the 'mask'-
1755 // case, or if the clip ends up empty.
1756 clipStateSaver.save();
1757 if (!rootRelativeBoundsComputed) {
1758 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1759 rootRelativeBoundsComputed = true;
1762 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer()));
1763 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativeBounds,
1764 paintingInfo.paintDirtyRect, context, clipperState)) {
1765 // No need to post-apply the clipper if this failed.
1766 resourceClipper = 0;
1772 // Blending operations must be performed only with the nearest ancestor stacking context.
1773 // Note that there is no need to create a transparency layer if we're painting the root.
1774 bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && hasDescendantWithBlendMode();
1776 if (createTransparencyLayerForBlendMode)
1777 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
1779 LayerPaintingInfo localPaintingInfo(paintingInfo);
1780 bool deferredFiltersEnabled = renderer()->document().settings()->deferredFiltersEnabled();
1781 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
1783 LayerFragments layerFragments;
1784 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
1785 // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
1786 // fragment should paint.
1787 collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
1788 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
1789 shouldRespectOverflowClip(paintFlags, renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
1790 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
1793 if (filterPainter.haveFilterEffect()) {
1794 ASSERT(this->filterInfo());
1796 if (!rootRelativeBoundsComputed)
1797 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1799 if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect)) {
1801 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
1802 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
1803 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that
1804 // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method.
1805 // With deferred filters, we don't need a separate context, but we do need to do transparency and clipping before starting
1806 // filter processing.
1807 // FIXME: when the legacy path is removed, remove the transparencyLayerContext as well.
1808 if (deferredFiltersEnabled) {
1809 if (haveTransparency) {
1810 // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one after filter processing.
1811 beginTransparencyLayers(context, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
1813 // We'll handle clipping to the dirty rect before filter rasterization.
1814 // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets.
1815 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
1816 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
1817 clipToRect(localPaintingInfo, context, backgroundRect, paintFlags);
1818 // Subsequent code should not clip to the dirty rect, since we've already
1819 // done it above, and doing it later will defeat the outsets.
1820 localPaintingInfo.clipToDirtyRect = false;
1822 context = filterPainter.beginFilterEffect(context);
1824 // Check that we didn't fail to allocate the graphics context for the offscreen buffer.
1825 if (filterPainter.hasStartedFilterEffect() && !deferredFiltersEnabled) {
1826 localPaintingInfo.paintDirtyRect = filterPainter.paintInvalidationRect();
1827 // If the filter needs the full source image, we need to avoid using the clip rectangles.
1828 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
1829 // Note that we will still apply the clipping on the final rendering of the filter.
1830 localPaintingInfo.clipToDirtyRect = !filterRenderer()->hasFilterThatMovesPixels();
1835 if (filterPainter.hasStartedFilterEffect() && haveTransparency && !deferredFiltersEnabled) {
1836 // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.
1837 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
1840 // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
1841 // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
1842 // Else, our renderer tree may or may not contain the painting root, so we pass that root along
1843 // so it will be tested against as we descend through the renderers.
1844 RenderObject* paintingRootForRenderer = 0;
1845 if (localPaintingInfo.paintingRoot && !renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
1846 paintingRootForRenderer = localPaintingInfo.paintingRoot;
1848 ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText));
1849 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
1851 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
1852 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground);
1853 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent;
1854 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground;
1855 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars;
1856 bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly;
1857 bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly;
1859 PaintBehavior paintBehavior = PaintBehaviorNormal;
1860 if (paintFlags & PaintLayerPaintingSkipRootBackground)
1861 paintBehavior |= PaintBehaviorSkipRootBackground;
1862 else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
1863 paintBehavior |= PaintBehaviorRootBackgroundOnly;
1865 if (shouldPaintBackground) {
1866 paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
1867 localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
1870 if (shouldPaintNegZOrderList)
1871 paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags);
1873 if (shouldPaintOwnContents) {
1874 paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
1875 localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags);
1878 if (shouldPaintOutline)
1879 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
1881 if (shouldPaintNormalFlowAndPosZOrderLists)
1882 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags);
1884 if (shouldPaintOverlayScrollbars)
1885 paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
1887 if (filterPainter.hasStartedFilterEffect()) {
1888 // Apply the correct clipping (ie. overflow: hidden).
1889 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
1890 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
1891 if (!deferredFiltersEnabled)
1892 clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect, paintFlags);
1894 context = filterPainter.applyFilterEffect();
1895 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
1898 // Make sure that we now use the original transparency context.
1899 ASSERT(transparencyLayerContext == context);
1901 if (shouldPaintMask)
1902 paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
1904 if (shouldPaintClippingMask) {
1905 // Paint the border radius mask for the fragments.
1906 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
1909 // End our transparency layer
1910 if ((haveTransparency || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency && !(m_reflectionInfo && m_reflectionInfo->isPaintingInsideReflection())) {
1911 context->endLayer();
1913 m_usedTransparency = false;
1916 if (resourceClipper)
1917 resourceClipper->postApplyStatefulResource(renderer(), context, clipperState);
1920 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset)
1922 // This involves subtracting out the position of the layer in our current coordinate space, but preserving
1923 // the accumulated error for sub-pixel layout.
1925 convertToLayerCoords(paintingInfo.rootLayer, delta);
1926 delta.moveBy(translationOffset);
1927 TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
1928 IntPoint roundedDelta = roundedIntPoint(delta);
1929 transform.translateRight(roundedDelta.x(), roundedDelta.y());
1930 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
1932 // Apply the transform.
1933 GraphicsContextStateSaver stateSaver(*context, false);
1934 if (!transform.isIdentity()) {
1936 context->concatCTM(transform.toAffineTransform());
1939 // Now do a paint with the root layer shifted to be us.
1940 LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior,
1941 adjustedSubPixelAccumulation, paintingInfo.paintingRoot);
1942 paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
1945 bool RenderLayer::shouldPaintLayerInSoftwareMode(const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1947 DisableCompositingQueryAsserts disabler;
1949 return compositingState() == NotComposited
1950 || compositingState() == HasOwnBackingButPaintsIntoAncestor
1951 || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)
1952 || ((paintFlags & PaintLayerPaintingReflection) && !has3DTransform())
1953 || paintForFixedRootBackground(this, paintFlags);
1956 void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1958 if (!hasSelfPaintingLayerDescendant())
1962 LayerListMutationDetector mutationChecker(m_stackingNode.get());
1965 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit);
1966 while (RenderLayerStackingNode* child = iterator.next()) {
1967 RenderLayer* childLayer = child->layer();
1968 // If this RenderLayer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents()
1969 // and CompositedLayerMapping::doPaintTask().
1970 if (!childLayer->shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags))
1973 if (!childLayer->isPaginated())
1974 childLayer->paintLayer(context, paintingInfo, paintFlags);
1976 paintPaginatedChildLayer(childLayer, context, paintingInfo, paintFlags);
1980 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
1981 ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
1982 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
1984 if (!enclosingPaginationLayer() || hasTransform()) {
1985 // For unpaginated layers, there is only one fragment.
1986 LayerFragment fragment;
1987 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy, subPixelAccumulation);
1988 if (respectOverflowClip == IgnoreOverflowClip)
1989 clipRectsContext.setIgnoreOverflowClip();
1990 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
1991 fragments.append(fragment);
1995 // Compute our offset within the enclosing pagination layer.
1996 LayoutPoint offsetWithinPaginatedLayer;
1997 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer);
1999 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
2000 // 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.
2001 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
2002 if (respectOverflowClip == IgnoreOverflowClip)
2003 paginationClipRectsContext.setIgnoreOverflowClip();
2004 LayoutRect layerBoundsInFlowThread;
2005 ClipRect backgroundRectInFlowThread;
2006 ClipRect foregroundRectInFlowThread;
2007 ClipRect outlineRectInFlowThread;
2008 clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
2009 outlineRectInFlowThread, &offsetWithinPaginatedLayer);
2011 // Take our bounding box within the flow thread and clip it.
2012 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer);
2013 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
2015 // Shift the dirty rect into flow thread coordinates.
2016 LayoutPoint offsetOfPaginationLayerFromRoot;
2017 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
2018 LayoutRect dirtyRectInFlowThread(dirtyRect);
2019 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot);
2021 // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
2022 // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
2023 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
2024 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
2026 if (fragments.isEmpty())
2029 // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
2030 ClipRect ancestorClipRect = dirtyRect;
2031 if (enclosingPaginationLayer()->parent()) {
2032 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
2033 if (respectOverflowClip == IgnoreOverflowClip)
2034 clipRectsContext.setIgnoreOverflowClip();
2035 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
2036 ancestorClipRect.intersect(dirtyRect);
2039 for (size_t i = 0; i < fragments.size(); ++i) {
2040 LayerFragment& fragment = fragments.at(i);
2042 // Set our four rects with all clipping applied that was internal to the flow thread.
2043 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread);
2045 // Shift to the root-relative physical position used when painting the flow thread in this fragment.
2046 fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2048 // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
2049 // properly clipped by the overflow.
2050 fragment.intersect(ancestorClipRect.rect());
2052 // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
2053 // clip, so the column clip ends up being all we apply.
2054 fragment.intersect(fragment.paginationClip);
2058 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags,
2059 bool shouldPaintContent, const LayoutPoint* offsetFromRoot)
2061 ASSERT(offsetFromRoot);
2062 for (size_t i = 0; i < fragments.size(); ++i) {
2063 LayerFragment& fragment = fragments.at(i);
2064 fragment.shouldPaintContent = shouldPaintContent;
2065 if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) {
2066 LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset;
2067 fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot);
2072 void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2074 LayerFragments enclosingPaginationFragments;
2075 LayoutPoint offsetOfPaginationLayerFromRoot;
2076 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
2077 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
2078 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
2079 shouldRespectOverflowClip(paintFlags, renderer()), &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent);
2081 for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
2082 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
2084 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
2085 // the enclosing pagination layer.
2086 LayoutRect clipRect = fragment.backgroundRect.rect();
2088 // Now compute the clips within a given fragment
2089 if (parent() != enclosingPaginationLayer()) {
2090 enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot);
2092 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize);
2093 if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip)
2094 clipRectsContext.setIgnoreOverflowClip();
2095 LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
2096 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2097 clipRect.intersect(parentClipRect);
2100 parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
2101 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
2102 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
2106 static inline LayoutSize subPixelAccumulationIfNeeded(const LayoutSize& subPixelAccumulation, CompositingState compositingState)
2108 // Only apply the sub-pixel accumulation if we don't paint into our own backing layer, otherwise the position
2109 // of the renderer already includes any sub-pixel offset.
2110 if (compositingState == PaintsIntoOwnBacking)
2111 return LayoutSize();
2112 return subPixelAccumulation;
2115 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
2116 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
2117 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2119 for (size_t i = 0; i < layerFragments.size(); ++i) {
2120 const LayerFragment& fragment = layerFragments.at(i);
2121 if (!fragment.shouldPaintContent)
2124 // Begin transparency layers lazily now that we know we have to paint something.
2125 if (haveTransparency || paintsWithBlendMode())
2126 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
2128 if (localPaintingInfo.clipToDirtyRect) {
2129 // Paint our background first, before painting any child layers.
2130 // Establish the clip used to paint our background.
2131 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
2134 // Paint the background.
2135 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
2136 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2137 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2139 if (localPaintingInfo.clipToDirtyRect)
2140 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2144 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
2145 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
2146 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags paintFlags)
2148 // Begin transparency if we have something to paint.
2149 if (haveTransparency || paintsWithBlendMode()) {
2150 for (size_t i = 0; i < layerFragments.size(); ++i) {
2151 const LayerFragment& fragment = layerFragments.at(i);
2152 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
2153 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
2159 // Optimize clipping for the single fragment case.
2160 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
2162 clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags);
2164 // We have to loop through every fragment multiple times, since we have to issue paint invalidations in each specific phase in order for
2165 // interleaving of the fragments to work properly.
2166 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments,
2167 context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2169 if (!selectionOnly) {
2170 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2171 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2172 paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2176 restoreClip(context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
2179 void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context,
2180 const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2182 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1;
2184 for (size_t i = 0; i < layerFragments.size(); ++i) {
2185 const LayerFragment& fragment = layerFragments.at(i);
2186 if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty())
2190 clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags);
2192 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2193 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2196 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2200 void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2201 PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2203 for (size_t i = 0; i < layerFragments.size(); ++i) {
2204 const LayerFragment& fragment = layerFragments.at(i);
2205 if (fragment.outlineRect.isEmpty())
2208 // Paint our own outline
2209 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2210 clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, DoNotIncludeSelfForBorderRadius);
2211 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2212 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
2216 void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2217 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2219 for (size_t i = 0; i < layerFragments.size(); ++i) {
2220 const LayerFragment& fragment = layerFragments.at(i);
2221 if (!fragment.shouldPaintContent)
2224 if (localPaintingInfo.clipToDirtyRect)
2225 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
2228 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
2229 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2230 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2232 if (localPaintingInfo.clipToDirtyRect)
2233 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2237 void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2238 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2240 for (size_t i = 0; i < layerFragments.size(); ++i) {
2241 const LayerFragment& fragment = layerFragments.at(i);
2242 if (!fragment.shouldPaintContent)
2245 if (localPaintingInfo.clipToDirtyRect)
2246 clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
2248 // Paint the the clipped mask.
2249 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2250 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2252 if (localPaintingInfo.clipToDirtyRect)
2253 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2257 void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags)
2259 for (size_t i = 0; i < layerFragments.size(); ++i) {
2260 const LayerFragment& fragment = layerFragments.at(i);
2261 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags);
2262 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
2263 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
2264 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2268 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2270 // We need to do multiple passes, breaking up our child layer into strips.
2271 Vector<RenderLayer*> columnLayers;
2272 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
2273 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
2274 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
2275 columnLayers.append(curr);
2276 if (curr->stackingNode() == ancestorNode)
2280 // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before
2281 // updatePaginationRecusive() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
2282 // If this is the case, just bail out, since the upcoming call to updatePaginationRecusive() will paint invalidate the layer.
2283 // FIXME: Is this true anymore? This seems very suspicious.
2284 if (!columnLayers.size())
2287 paintChildLayerIntoColumns(childLayer, context, paintingInfo, paintFlags, columnLayers, columnLayers.size() - 1);
2290 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo,
2291 PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex)
2293 RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer());
2295 ASSERT(columnBlock && columnBlock->hasColumns());
2296 if (!columnBlock || !columnBlock->hasColumns())
2299 LayoutPoint layerOffset;
2300 // FIXME: It looks suspicious to call convertToLayerCoords here
2301 // as canUseConvertToLayerCoords is true for this layer.
2302 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffset);
2304 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
2306 ColumnInfo* colInfo = columnBlock->columnInfo();
2307 unsigned colCount = columnBlock->columnCount(colInfo);
2308 LayoutUnit currLogicalTopOffset = 0;
2309 for (unsigned i = 0; i < colCount; i++) {
2310 // For each rect, we clip to the rect, and then we adjust our coords.
2311 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2312 columnBlock->flipForWritingMode(colRect);
2313 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
2316 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2317 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset);
2319 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
2321 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2322 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset);
2324 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
2327 colRect.moveBy(layerOffset);
2329 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect);
2330 localDirtyRect.intersect(colRect);
2332 if (!localDirtyRect.isEmpty()) {
2333 GraphicsContextStateSaver stateSaver(*context);
2335 // Each strip pushes a clip, since column boxes are specified as being
2336 // like overflow:hidden.
2337 context->clip(enclosingIntRect(colRect));
2340 // Apply a translation transform to change where the layer paints.
2341 TransformationMatrix oldTransform;
2342 bool oldHasTransform = childLayer->transform();
2343 if (oldHasTransform)
2344 oldTransform = *childLayer->transform();
2345 TransformationMatrix newTransform(oldTransform);
2346 newTransform.translateRight(roundToInt(offset.width()), roundToInt(offset.height()));
2348 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
2350 LayerPaintingInfo localPaintingInfo(paintingInfo);
2351 localPaintingInfo.paintDirtyRect = localDirtyRect;
2352 childLayer->paintLayer(context, localPaintingInfo, paintFlags);
2354 if (oldHasTransform)
2355 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
2357 childLayer->m_transform.clear();
2359 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
2360 // This involves subtracting out the position of the layer in our current coordinate space.
2361 LayoutPoint childOffset;
2362 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.rootLayer, childOffset);
2363 TransformationMatrix transform;
2364 transform.translateRight(roundToInt(childOffset.x() + offset.width()), roundToInt(childOffset.y() + offset.height()));
2366 // Apply the transform.
2367 context->concatCTM(transform.toAffineTransform());
2369 // Now do a paint with the root layer shifted to be the next multicol block.
2370 LayerPaintingInfo columnPaintingInfo(paintingInfo);
2371 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1];
2372 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(localDirtyRect);
2373 paintChildLayerIntoColumns(childLayer, context, columnPaintingInfo, paintFlags, columnLayers, colIndex - 1);
2377 // Move to the next position.
2378 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width();
2379 if (columnBlock->style()->isFlippedBlocksWritingMode())
2380 currLogicalTopOffset += blockDelta;
2382 currLogicalTopOffset -= blockDelta;
2386 static inline LayoutRect frameVisibleRect(RenderObject* renderer)
2388 FrameView* frameView = renderer->document().view();
2390 return LayoutRect();
2392 return frameView->visibleContentRect();
2395 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
2397 return hitTest(request, result.hitTestLocation(), result);
2400 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result)
2402 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
2404 // RenderView should make sure to update layout before entering hit testing
2405 ASSERT(!renderer()->frame()->view()->layoutPending());
2406 ASSERT(!renderer()->document().renderView()->needsLayout());
2408 LayoutRect hitTestArea = renderer()->view()->documentRect();
2409 if (!request.ignoreClipping())
2410 hitTestArea.intersect(frameVisibleRect(renderer()));
2412 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hitTestLocation, false);
2414 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
2415 // return ourselves. We do this so mouse events continue getting delivered after a drag has
2416 // exited the WebView, and so hit testing over a scrollbar hits the content document.
2417 // In addtion, it is possible for the mouse to stay in the document but there is no element.
2418 // At that time, the events of the mouse should be fired.
2419 LayoutPoint hitPoint = hitTestLocation.point();
2420 if (!request.isChildFrameHitTest() && ((request.active() || request.release()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y()))) && isRootLayer()) {
2421 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point()));
2426 // Now determine if the result is inside an anchor - if the urlElement isn't already set.
2427 Node* node = result.innerNode();
2428 if (node && !result.URLElement())
2429 result.setURLElement(node->enclosingLinkEventParentOrSelf());
2431 // Now return whether we were inside this layer (this will always be true for the root
2436 Node* RenderLayer::enclosingElement() const
2438 for (RenderObject* r = renderer(); r; r = r->parent()) {
2439 if (Node* e = r->node())
2442 ASSERT_NOT_REACHED();
2446 bool RenderLayer::isInTopLayer() const
2448 Node* node = renderer()->node();
2449 return node && node->isElementNode() && toElement(node)->isInTopLayer();
2452 // Compute the z-offset of the point in the transformState.
2453 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
2454 // ray intersects target, and computing the z delta between those two points.
2455 static double computeZOffset(const HitTestingTransformState& transformState)
2457 // We got an affine transform, so no z-offset
2458 if (transformState.m_accumulatedTransform.isAffine())
2461 // Flatten the point into the target plane
2462 FloatPoint targetPoint = transformState.mappedPoint();
2464 // Now map the point back through the transform, which computes Z.
2465 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
2466 return backmappedPoint.z();
2469 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
2470 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
2471 const HitTestingTransformState* containerTransformState,
2472 const LayoutPoint& translationOffset) const
2474 RefPtr<HitTestingTransformState> transformState;
2476 if (containerTransformState) {
2477 // If we're already computing transform state, then it's relative to the container (which we know is non-null).
2478 transformState = HitTestingTransformState::create(*containerTransformState);
2479 convertToLayerCoords(containerLayer, offset);
2481 // If this is the first time we need to make transform state, then base it off of hitTestLocation,
2482 // which is relative to rootLayer.
2483 transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect));
2484 convertToLayerCoords(rootLayer, offset);
2486 offset.moveBy(translationOffset);
2488 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
2489 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
2490 TransformationMatrix containerTransform;
2491 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform);
2492 transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
2494 transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform);
2497 return transformState;
2501 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
2506 // The hit layer is depth-sorting with other layers, so just say that it was hit.
2510 // We need to look at z-depth to decide if this layer was hit.
2512 ASSERT(transformState);
2513 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
2514 double childZOffset = computeZOffset(*transformState);
2515 if (childZOffset > *zOffset) {
2516 *zOffset = childZOffset;
2525 // hitTestLocation and hitTestRect are relative to rootLayer.
2526 // A 'flattening' layer is one preserves3D() == false.
2527 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
2528 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer.
2529 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
2531 // If zOffset is non-null (which indicates that the caller wants z offset information),
2532 // *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
2533 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2534 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform,
2535 const HitTestingTransformState* transformState, double* zOffset)
2537 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
2540 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
2542 // Apply a transform if we have one.
2543 if (transform() && !appliedTransform) {
2544 if (enclosingPaginationLayer())
2545 return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
2547 // Make sure the parent's clip rects have been calculated.
2549 ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize));
2550 // Go ahead and test the enclosing clip now.
2551 if (!clipRect.intersects(hitTestLocation))
2555 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
2558 // Ensure our lists and 3d status are up-to-date.
2559 m_stackingNode->updateLayerListsIfNeeded();
2560 update3DTransformedDescendantStatus();
2562 RefPtr<HitTestingTransformState> localTransformState;
2563 if (appliedTransform) {
2564 // We computed the correct state in the caller (above code), so just reference it.
2565 ASSERT(transformState);
2566 localTransformState = const_cast<HitTestingTransformState*>(transformState);
2567 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
2568 // We need transform state for the first time, or to offset the container state, so create it here.
2569 localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
2572 // Check for hit test on backface if backface-visibility is 'hidden'
2573 if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
2574 TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
2575 // If the z-vector of the matrix is negative, the back is facing towards the viewer.
2576 if (invertedMatrix.m33() < 0)
2580 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
2581 if (localTransformState && !preserves3D()) {
2582 // Keep a copy of the pre-flattening state, for computing z-offsets for the container
2583 unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
2584 // This layer is flattening, so flatten the state passed to descendants.
2585 localTransformState->flatten();
2588 // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
2590 double localZOffset = -std::numeric_limits<double>::infinity();
2591 double* zOffsetForDescendantsPtr = 0;
2592 double* zOffsetForContentsPtr = 0;
2594 bool depthSortDescendants = false;
2595 if (preserves3D()) {
2596 depthSortDescendants = true;
2597 // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
2598 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
2599 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
2600 } else if (zOffset) {
2601 zOffsetForDescendantsPtr = 0;
2602 // Container needs us to give back a z offset for the hit layer.
2603 zOffsetForContentsPtr = zOffset;
2606 // This variable tracks which layer the mouse ends up being inside.
2607 RenderLayer* candidateLayer = 0;
2609 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
2610 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2611 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2613 if (!depthSortDescendants)
2615 candidateLayer = hitLayer;
2618 // Now check our overflow objects.
2619 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2620 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2622 if (!depthSortDescendants)
2624 candidateLayer = hitLayer;
2627 // Collect the fragments. This will compute the clip rectangles for each layer fragment.
2628 LayerFragments layerFragments;
2629 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
2631 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) {
2632 renderer()->updateHitTestResult(result, hitTestLocation.point());
2636 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check
2637 // every fragment in reverse order.
2638 if (isSelfPaintingLayer()) {
2639 // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
2640 HitTestResult tempResult(result.hitTestLocation());
2641 bool insideFragmentForegroundRect = false;
2642 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect)
2643 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
2644 if (result.isRectBasedTest())
2645 result.append(tempResult);
2647 result = tempResult;
2648 if (!depthSortDescendants)
2650 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
2651 candidateLayer = this;
2652 } else if (insideFragmentForegroundRect && result.isRectBasedTest())
2653 result.append(tempResult);
2656 // Now check our negative z-index children.
2657 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2658 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2660 if (!depthSortDescendants)
2662 candidateLayer = hitLayer;
2665 // If we found a layer, return. Child layers, and foreground always render in front of background.
2667 return candidateLayer;
2669 if (isSelfPaintingLayer()) {
2670 HitTestResult tempResult(result.hitTestLocation());
2671 bool insideFragmentBackgroundRect = false;
2672 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect)
2673 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
2674 if (result.isRectBasedTest())
2675 result.append(tempResult);
2677 result = tempResult;
2680 if (insideFragmentBackgroundRect && result.isRectBasedTest())
2681 result.append(tempResult);
2687 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result,
2688 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const
2690 if (layerFragments.isEmpty())
2693 for (int i = layerFragments.size() - 1; i >= 0; --i) {
2694 const LayerFragment& fragment = layerFragments.at(i);
2695 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation))
2696 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation)))
2698 insideClipRect = true;
2699 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter))
2706 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2707 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2709 LayerFragments enclosingPaginationFragments;
2710 LayoutPoint offsetOfPaginationLayerFromRoot;
2711 // FIXME: We're missing a sub-pixel offset here crbug.com/348728
2712 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox, LayoutSize());
2713 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
2714 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
2716 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
2717 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
2719 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
2720 // the enclosing pagination layer.
2721 LayoutRect clipRect = fragment.backgroundRect.rect();
2723 // Now compute the clips within a given fragment
2724 if (parent() != enclosingPaginationLayer()) {
2725 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
2726 LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize)).rect();
2727 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2728 clipRect.intersect(parentClipRect);
2731 if (!hitTestLocation.intersects(clipRect))
2734 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation,
2735 transformState, zOffset, fragment.paginationOffset);
2743 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2744 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
2745 const LayoutPoint& translationOffset)
2747 // Create a transform state to accumulate this transform.
2748 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset);
2750 // If the transform can't be inverted, then don't hit test this layer at all.
2751 if (!newTransformState->m_accumulatedTransform.isInvertible())
2754 // Compute the point and the hit test rect in the coords of this layer by using the values
2755 // from the transformState, which store the point and quad in the coords of the last flattened
2756 // layer, and the accumulated transform which lets up map through preserve-3d layers.
2758 // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z)
2759 // by our container.
2760 FloatPoint localPoint = newTransformState->mappedPoint();
2761 FloatQuad localPointQuad = newTransformState->mappedQuad();
2762 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea();
2763 HitTestLocation newHitTestLocation;
2764 if (hitTestLocation.isRectBasedTest())
2765 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
2767 newHitTestLocation = HitTestLocation(localPoint);
2769 // Now do a hit test with the root layer shifted to be us.
2770 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset);
2773 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const
2775 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
2777 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) {
2778 // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
2779 // a rect-based test.
2780 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
2784 // For positioned generated content, we might still not have a
2785 // node by the time we get to the layer level, since none of
2786 // the content in the layer has an element. So just walk up
2788 if (!result.innerNode() || !result.innerNonSharedNode()) {
2789 Node* e = enclosingElement();
2790 if (!result.innerNode())
2791 result.setInnerNode(e);
2792 if (!result.innerNonSharedNode())
2793 result.setInnerNonSharedNode(e);
2799 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer,
2800 const HitTestRequest& request, HitTestResult& result,
2801 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
2802 const HitTestingTransformState* transformState,
2803 double* zOffsetForDescendants, double* zOffset,
2804 const HitTestingTransformState* unflattenedTransformState,
2805 bool depthSortDescendants)
2807 if (!hasSelfPaintingLayerDescendant())
2810 RenderLayer* resultLayer = 0;
2811 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit);
2812 while (RenderLayerStackingNode* child = iterator.next()) {
2813 RenderLayer* childLayer = child->layer();
2814 RenderLayer* hitLayer = 0;
2815 HitTestResult tempResult(result.hitTestLocation());
2816 if (childLayer->isPaginated())
2817 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
2819 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
2821 // If it a rect-based test, we can safely append the temporary result since it might had hit
2822 // nodes but not necesserily had hitLayer set.
2823 if (result.isRectBasedTest())
2824 result.append(tempResult);
2826 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
2827 resultLayer = hitLayer;
2828 if (!result.isRectBasedTest())
2829 result = tempResult;
2830 if (!depthSortDescendants)
2838 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
2839 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2841 Vector<RenderLayer*> columnLayers;
2842 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
2843 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
2844 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
2845 columnLayers.append(curr);
2846 if (curr->stackingNode() == ancestorNode)
2850 ASSERT(columnLayers.size());
2851 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset,
2852 columnLayers, columnLayers.size() - 1);
2855 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
2856 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
2857 const Vector<RenderLayer*>& columnLayers, size_t columnIndex)
2859 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer());
2861 ASSERT(columnBlock && columnBlock->hasColumns());
2862 if (!columnBlock || !columnBlock->hasColumns())
2865 LayoutPoint layerOffset;
2866 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
2868 ColumnInfo* colInfo = columnBlock->columnInfo();
2869 int colCount = columnBlock->columnCount(colInfo);
2871 // We have to go backwards from the last column to the first.
2872 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
2873 LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent();
2874 LayoutUnit currLogicalTopOffset = 0;
2876 for (i = 0; i < colCount; i++) {
2877 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2878 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
2879 if (columnBlock->style()->isFlippedBlocksWritingMode())
2880 currLogicalTopOffset += blockDelta;
2882 currLogicalTopOffset -= blockDelta;
2884 for (i = colCount - 1; i >= 0; i--) {
2885 // For each rect, we clip to the rect, and then we adjust our coords.
2886 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2887 columnBlock->flipForWritingMode(colRect);
2888 LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
2889 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
2890 if (columnBlock->style()->isFlippedBlocksWritingMode())
2891 currLogicalTopOffset -= blockDelta;
2893 currLogicalTopOffset += blockDelta;
2897 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2898 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset);
2900 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
2902 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2903 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset);
2905 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
2908 colRect.moveBy(layerOffset);
2910 LayoutRect localClipRect(hitTestRect);
2911 localClipRect.intersect(colRect);
2913 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect)) {
2914 RenderLayer* hitLayer = 0;
2916 // Apply a translation transform to change where the layer paints.
2917 TransformationMatrix oldTransform;
2918 bool oldHasTransform = childLayer->transform();
2919 if (oldHasTransform)
2920 oldTransform = *childLayer->transform();
2921 TransformationMatrix newTransform(oldTransform);
2922 newTransform.translateRight(offset.width(), offset.height());
2924 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
2925 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestLocation, false, transformState, zOffset);
2926 if (oldHasTransform)
2927 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
2929 childLayer->m_transform.clear();
2931 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space.
2932 // This involves subtracting out the position of the layer in our current coordinate space.
2933 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
2934 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation, transformState);
2935 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
2936 FloatPoint localPoint = newTransformState->mappedPoint();
2937 FloatQuad localPointQuad = newTransformState->mappedQuad();
2938 LayoutRect localHitTestRect = newTransformState->mappedArea().enclosingBoundingBox();
2939 HitTestLocation newHitTestLocation;
2940 if (hitTestLocation.isRectBasedTest())
2941 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
2943 newHitTestLocation = HitTestLocation(localPoint);
2944 newTransformState->flatten();
2946 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, newHitTestLocation,
2947 newTransformState.get(), zOffset, columnLayers, columnIndex - 1);
2958 void RenderLayer::blockSelectionGapsBoundsChanged()
2960 setNeedsCompositingInputsUpdate();
2963 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
2965 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
2966 blockSelectionGapsBoundsChanged();
2969 void RenderLayer::clearBlockSelectionGapsBounds()
2971 m_blockSelectionGapsBounds = IntRect();
2972 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2973 child->clearBlockSelectionGapsBounds();
2974 blockSelectionGapsBoundsChanged();
2977 void RenderLayer::invalidatePaintForBlockSelectionGaps()
2979 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2980 child->invalidatePaintForBlockSelectionGaps();
2982 if (m_blockSelectionGapsBounds.isEmpty())
2985 LayoutRect rect = m_blockSelectionGapsBounds;
2986 if (renderer()->hasOverflowClip()) {
2987 RenderBox* box = renderBox();
2988 rect.move(-box->scrolledContentOffset());
2989 if (!scrollableArea()->usesCompositedScrolling())
2990 rect.intersect(box->overflowClipRect(LayoutPoint()));
2992 if (renderer()->hasClip())
2993 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint()));
2994 if (!rect.isEmpty())
2995 renderer()->invalidatePaintRectangle(rect);
2998 IntRect RenderLayer::blockSelectionGapsBounds() const
3000 if (!renderer()->isRenderBlock())
3003 RenderBlock* renderBlock = toRenderBlock(renderer());
3004 LayoutRect gapRects = renderBlock->selectionGapRectsForPaintInvalidation(renderBlock);
3006 return pixelSnappedIntRect(gapRects);
3009 bool RenderLayer::hasBlockSelectionGapBounds() const
3011 // FIXME: it would be more accurate to return !blockSelectionGapsBounds().isEmpty(), but this is impossible
3012 // at the moment because it causes invalid queries to layout-dependent code (crbug.com/372802).
3013 // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::LayoutClean);
3015 if (!renderer()->isRenderBlock())
3018 return toRenderBlock(renderer())->shouldPaintSelectionGaps();
3021 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
3023 // Always examine the canvas and the root.
3024 // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
3025 // paints the root's background.
3026 if (isRootLayer() || renderer()->isDocumentElement())
3029 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
3030 // can go ahead and return true.
3031 RenderView* view = renderer()->view();
3033 if (view && !renderer()->isRenderInline()) {
3034 if (layerBounds.intersects(damageRect))
3038 // Otherwise we need to compute the bounding box of this single layer and see if it intersects
3040 return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
3043 LayoutRect RenderLayer::logicalBoundingBox() const
3045 // There are three special cases we need to consider.
3046 // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
3047 // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the
3048 // line boxes of all three lines (including overflow on those lines).
3049 // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top
3050 // overflow, we have to create a bounding box that will extend to include this overflow.
3051 // (3) Floats. When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
3052 // as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
3055 if (renderer()->isInline() && renderer()->isRenderInline()) {
3056 result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
3057 } else if (renderer()->isTableRow()) {
3058 // Our bounding box is just the union of all of our cells' border/overflow rects.
3059 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
3060 if (child->isTableCell()) {
3061 LayoutRect bbox = toRenderBox(child)->borderBoxRect();
3063 LayoutRect overflowRect = renderBox()->visualOverflowRect();
3064 if (bbox != overflowRect)
3065 result.unite(overflowRect);
3069 RenderBox* box = renderBox();
3071 result = box->borderBoxRect();
3072 result.unite(box->visualOverflowRect());
3075 ASSERT(renderer()->view());
3079 LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const
3081 LayoutRect result = logicalBoundingBox();
3082 if (m_renderer->isBox())
3083 renderBox()->flipForWritingMode(result);
3085 m_renderer->containingBlock()->flipForWritingMode(result);
3089 delta = *offsetFromRoot;
3091 convertToLayerCoords(ancestorLayer, delta);
3093 result.moveBy(delta);
3097 static void expandRectForReflectionAndStackingChildren(const RenderLayer* ancestorLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result)
3099 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
3100 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer));
3102 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer->stackingNode()->hasPositiveZOrderList());
3105 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(ancestorLayer)->stackingNode());
3108 RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildren);
3109 while (RenderLayerStackingNode* node = iterator.next()) {
3110 // Here we exclude both directly composited layers and squashing layers
3111 // because those RenderLayers don't paint into the graphics layer
3112 // for this RenderLayer. For example, the bounds of squashed RenderLayers
3113 // will be included in the computation of the appropriate squashing
3115 if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()->compositingState() != NotComposited)
3117 result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options));
3121 LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const
3124 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
3126 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
3128 expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggHacks, result);
3130 result.moveBy(offsetFromRoot);
3134 LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLayer, CalculateBoundsOptions options) const
3136 if (!isSelfPaintingLayer())
3137 return LayoutRect();
3140 ancestorLayer = this;
3142 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
3143 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
3144 return LayoutRect();
3146 // The root layer is always just the size of the document.
3148 return m_renderer->view()->unscaledDocumentRect();
3150 const bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform());
3152 LayoutRect localClipRect = clipper().localClipRect();
3153 if (localClipRect != PaintInfo::infiniteRect()) {
3154 if (shouldIncludeTransform)
3155 localClipRect = transform()->mapRect(localClipRect);
3158 convertToLayerCoords(ancestorLayer, delta);
3159 localClipRect.moveBy(delta);
3160 return localClipRect;
3164 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
3166 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
3168 // Reflections are implemented with RenderLayers that hang off of the reflected layer. However,
3169 // the reflection layer subtree does not include the subtree of the parent RenderLayer, so
3170 // a recursive computation of stacking children yields no results. This breaks cases when there are stacking
3171 // children of the parent, that need to be included in reflected composited bounds.
3172 // Fix this by including composited bounds of stacking children of the reflected RenderLayer.
3173 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this)
3174 expandRectForReflectionAndStackingChildren(parent(), options, result);
3176 expandRectForReflectionAndStackingChildren(this, options, result);
3178 // FIXME: We can optimize the size of the composited layers, by not enlarging
3179 // filtered areas with the outsets if we know that the filter is going to render in hardware.
3180 // https://bugs.webkit.org/show_bug.cgi?id=81239
3181 m_renderer->style()->filterOutsets().expandRect(result);
3183 if (shouldIncludeTransform)
3184 result = transform()->mapRect(result);
3187 convertToLayerCoords(ancestorLayer, delta);
3188 result.moveBy(delta);
3192 CompositingState RenderLayer::compositingState() const
3194 ASSERT(isAllowedToQueryCompositingState());
3196 // This is computed procedurally so there is no redundant state variable that
3197 // can get out of sync from the real actual compositing state.
3199 if (m_groupedMapping) {
3200 ASSERT(compositor()->layerSquashingEnabled());
3201 ASSERT(!m_compositedLayerMapping);
3202 return PaintsIntoGroupedBacking;
3205 if (!m_compositedLayerMapping)
3206 return NotComposited;
3208 if (compositedLayerMapping()->paintsIntoCompositedAncestor())
3209 return HasOwnBackingButPaintsIntoAncestor;
3211 return PaintsIntoOwnBacking;
3214 bool RenderLayer::isAllowedToQueryCompositingState() const
3216 if (gCompositingQueryMode == CompositingQueriesAreAllowed)
3218 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
3221 CompositedLayerMapping* RenderLayer::compositedLayerMapping() const
3223 ASSERT(isAllowedToQueryCompositingState());
3224 return m_compositedLayerMapping.get();
3227 GraphicsLayer* RenderLayer::graphicsLayerBacking() const
3229 switch (compositingState()) {
3232 case PaintsIntoGroupedBacking:
3233 return groupedMapping()->squashingLayer();
3235 return compositedLayerMapping()->mainGraphicsLayer();
3239 GraphicsLayer* RenderLayer::graphicsLayerBackingForScrolling() const
3241 switch (compositingState()) {
3244 case PaintsIntoGroupedBacking:
3245 return groupedMapping()->squashingLayer();
3247 return compositedLayerMapping()->scrollingContentsLayer() ? compositedLayerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsLayer();
3251 CompositedLayerMapping* RenderLayer::ensureCompositedLayerMapping()
3253 if (!m_compositedLayerMapping) {
3254 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this));
3255 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3257 updateOrRemoveFilterEffectRenderer();
3259 return m_compositedLayerMapping.get();
3262 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
3264 if (!layerBeingDestroyed) {
3265 // We need to make sure our decendants get a geometry update. In principle,
3266 // we could call setNeedsGraphicsLayerUpdate on our children, but that would
3267 // require walking the z-order lists to find them. Instead, we over-invalidate
3268 // by marking our parent as needing a geometry update.
3269 if (RenderLayer* compositingParent = enclosingLayerWithCompositedLayerMapping(ExcludeSelf))
3270 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3273 m_compositedLayerMapping.clear();
3275 if (!layerBeingDestroyed)
3276 updateOrRemoveFilterEffectRenderer();
3279 void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed)
3281 if (groupedMapping == m_groupedMapping)
3284 if (!layerBeingDestroyed && m_groupedMapping) {
3285 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3286 m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this);
3288 m_groupedMapping = groupedMapping;
3289 if (!layerBeingDestroyed && m_groupedMapping)
3290 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3293 bool RenderLayer::hasCompositedMask() const
3295 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
3298 bool RenderLayer::hasCompositedClippingMask() const
3300 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer();
3303 bool RenderLayer::clipsCompositingDescendantsWithBorderRadius() const
3305 RenderStyle* style = renderer()->style();
3309 return compositor()->clipsCompositingDescendants(this) && style->hasBorderRadius();
3312 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
3314 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
3317 bool RenderLayer::paintsWithBlendMode() const
3319 return m_renderer->hasBlendMode() && compositingState() != PaintsIntoOwnBacking;
3322 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
3324 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
3327 if (paintsWithTransparency(PaintBehaviorNormal))
3330 // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child
3331 // is visible and that child doesn't cover the entire rect.
3332 if (renderer()->style()->visibility() != VISIBLE)
3335 if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity())
3338 // FIXME: Handle simple transforms.
3339 if (paintsWithTransform(PaintBehaviorNormal))
3342 // FIXME: Remove this check.
3343 // This function should not be called when layer-lists are dirty.
3344 // It is somehow getting triggered during style update.
3345 if (m_stackingNode->zOrderListsDirty() || m_stackingNode->normalFlowListDirty())
3348 // FIXME: We currently only check the immediate renderer,
3349 // which will miss many cases.
3350 if (renderer()->backgroundIsKnownToBeOpaqueInRect(localRect))
3353 // We can't consult child layers if we clip, since they might cover
3354 // parts of the rect that are clipped out.
3355 if (renderer()->hasOverflowClip())
3358 return childBackgroundIsKnownToBeOpaqueInRect(localRect);
3361 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
3363 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren);
3364 while (RenderLayerStackingNode* child = revertseIterator.next()) {
3365 const RenderLayer* childLayer = child->layer();
3366 // Stop at composited paint boundaries.
3367 if (childLayer->isPaintInvalidationContainer())
3370 if (!childLayer->canUseConvertToLayerCoords())
3373 LayoutPoint childOffset;
3374 LayoutRect childLocalRect(localRect);
3375 childLayer->convertToLayerCoords(this, childOffset);
3376 childLocalRect.moveBy(-childOffset);
3378 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect))
3384 bool RenderLayer::shouldBeSelfPaintingLayer() const
3386 if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAcceleratedCompositing())
3388 return m_layerType == NormalLayer
3389 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
3390 || needsCompositedScrolling();
3393 void RenderLayer::updateSelfPaintingLayer()
3395 bool isSelfPaintingLayer = shouldBeSelfPaintingLayer();
3396 if (this->isSelfPaintingLayer() == isSelfPaintingLayer)
3399 m_isSelfPaintingLayer = isSelfPaintingLayer;
3402 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
3405 bool RenderLayer::hasNonEmptyChildRenderers() const
3407 // Some HTML can cause whitespace text nodes to have renderers, like:
3411 // so test for 0x0 RenderTexts here
3412 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
3413 if (!child->hasLayer()) {
3414 if (child->isRenderInline() || !child->isBox())
3417 if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
3424 bool RenderLayer::hasBoxDecorationsOrBackground() const
3426 return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasBackground();
3429 bool RenderLayer::hasVisibleBoxDecorations() const
3431 if (!hasVisibleContent())
3434 return hasBoxDecorationsOrBackground() || hasOverflowControls();
3437 bool RenderLayer::isVisuallyNonEmpty() const
3439 ASSERT(!m_visibleDescendantStatusDirty);
3441 if (hasVisibleContent() && hasNonEmptyChildRenderers())
3444 if (renderer()->isReplaced() || renderer()->hasMask())
3447 if (hasVisibleBoxDecorations())
3453 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
3455 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter()))
3458 updateOrRemoveFilterClients();
3459 updateOrRemoveFilterEffectRenderer();
3462 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const RenderStyle* oldStyle)
3464 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialCompositingReasonsFromStyle;
3465 compositor()->updatePotentialCompositingReasonsFromStyle(this);
3467 // This function implements an optimization for transforms and opacity.
3468 // A common pattern is for a touchmove handler to update the transform
3469 // and/or an opacity of an element every frame while the user moves their
3470 // finger across the screen. The conditions below recognize when the
3471 // compositing state is set up to receive a direct transform or opacity
3474 if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformChanged | StyleDifference::OpacityChanged))
3476 // The potentialCompositingReasonsFromStyle could have changed without
3477 // a corresponding StyleDifference if an animation started or ended.
3478 if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasonsFromStyle)
3480 // We could add support for reflections if we updated the transform on
3481 // the reflection layers.
3482 if (renderer()->hasReflection())
3484 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't
3485 // perform a direct compositing update because the filters code is going
3486 // to produce different output this time around. We can remove this code
3487 // once we fix the chicken/egg bugs in the filters code and delete the
3488 // scheduleSVGFilterLayerUpdateHack().
3489 if (renderer()->node() && renderer()->node()->svgFilterNeedsLayerUpdate())
3491 if (!m_compositedLayerMapping)
3494 // To cut off almost all the work in the compositing update for
3495 // this case, we treat inline transforms has having assumed overlap
3496 // (similar to how we treat animated transforms). Notice that we read
3497 // CompositingReasonInlineTransform from the m_compositingReasons, which
3498 // means that the inline transform actually triggered assumed overlap in
3500 if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInlineTransform))
3503 // We composite transparent RenderLayers differently from non-transparent
3504 // RenderLayers even when the non-transparent RenderLayers are already a
3505 // stacking context.
3506 if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->hasOpacity())
3509 updateTransform(oldStyle, renderer()->style());
3511 // FIXME: Consider introducing a smaller graphics layer update scope
3512 // that just handles transforms and opacity. GraphicsLayerUpdateLocal
3513 // will also program bounds, clips, and many other properties that could
3514 // not possibly have changed.
3515 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
3516 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange);
3520 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
3522 if (attemptDirectCompositingUpdate(diff, oldStyle))
3525 m_stackingNode->updateIsNormalFlowOnly();
3526 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
3528 if (m_scrollableArea)
3529 m_scrollableArea->updateAfterStyleChange(oldStyle);
3531 // Overlay scrollbars can make this layer self-painting so we need
3532 // to recompute the bit once scrollbars have been updated.
3533 updateSelfPaintingLayer();
3535 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
3536 ASSERT(!oldStyle || diff.needsFullLayout());
3537 updateReflectionInfo(oldStyle);
3540 updateDescendantDependentFlags();
3542 updateTransform(oldStyle, renderer()->style());
3543 updateFilters(oldStyle, renderer()->style());
3545 setNeedsCompositingInputsUpdate();
3548 bool RenderLayer::scrollsOverflow() const
3550 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
3551 return scrollableArea->scrollsOverflow();
3556 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
3558 const FilterOperations& filters = style->filter();
3559 if (filters.hasReferenceFilter()) {
3560 for (size_t i = 0; i < filters.size(); ++i) {
3561 FilterOperation* filterOperation = filters.operations().at(i).get();
3562 if (filterOperation->type() != FilterOperation::REFERENCE)
3564 ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
3565 // FIXME: Cache the ReferenceFilter if it didn't change.
3566 RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create();
3567 float zoom = style->effectiveZoom();
3568 referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom));
3569 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
3570 referenceOperation));
3571 referenceOperation->setFilter(referenceFilter.release());
3578 void RenderLayer::updateOrRemoveFilterClients()
3581 removeFilterInfoIfNeeded();
3585 if (renderer()->style()->filter().hasReferenceFilter())
3586 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter());
3587 else if (hasFilterInfo())
3588 filterInfo()->removeReferenceFilterClients();
3591 void RenderLayer::updateOrRemoveFilterEffectRenderer()
3593 // FilterEffectRenderer is only used to render the filters in software mode,
3594 // so we always need to run updateOrRemoveFilterEffectRenderer after the composited
3595 // mode might have changed for this layer.
3596 if (!paintsWithFilters()) {
3597 // Don't delete the whole filter info here, because we might use it
3598 // for loading CSS shader files.
3599 if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
3600 filterInfo->setRenderer(nullptr);
3605 RenderLayerFilterInfo* filterInfo = ensureFilterInfo();
3606 if (!filterInfo->renderer()) {
3607 RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
3608 filterInfo->setRenderer(filterRenderer.release());
3611 // If the filter fails to build, remove it from the layer. It will still attempt to
3612 // go through regular processing (e.g. compositing), but never apply anything.
3613 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
3614 filterInfo->setRenderer(nullptr);
3617 void RenderLayer::filterNeedsPaintInvalidation()
3620 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle());
3621 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style recalc, which
3622 // is a problem because this function can be called while performing layout.
3623 // Presumably this represents an illegal data flow of layout or compositing
3624 // information into the style system.
3625 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack();
3628 renderer()->setShouldDoFullPaintInvalidation(true);
3631 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const
3633 computeSelfHitTestRects(rects);
3634 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
3635 child->addLayerHitTestRects(rects);
3638 void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const
3640 if (!size().isEmpty()) {
3641 Vector<LayoutRect> rect;
3643 if (renderBox() && renderBox()->scrollsOverflow()) {
3644 // For scrolling layers, rects are taken to be in the space of the contents.
3645 // We need to include the bounding box of the layer in the space of its parent
3646 // (eg. for border / scroll bars) and if it's composited then the entire contents
3647 // as well as they may be on another composited layer. Skip reporting contents
3648 // for non-composited layers as they'll get projected to the same layer as the
3650 if (compositingState() != NotComposited)
3651 rect.append(m_scrollableArea->overflowRect());
3653 rects.set(this, rect);
3654 if (const RenderLayer* parentLayer = parent()) {
3655 LayerHitTestRects::iterator iter = rects.find(parentLayer);
3656 if (iter == rects.end()) {
3657 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(physicalBoundingBox(parentLayer));
3659 iter->value.append(physicalBoundingBox(parentLayer));
3663 rect.append(logicalBoundingBox());
3664 rects.set(this, rect);
3669 void RenderLayer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
3671 renderer()->setShouldDoFullPaintInvalidation(true);
3673 // Disable for reading compositingState() in isPaintInvalidationContainer() below.
3674 DisableCompositingQueryAsserts disabler;
3676 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
3677 if (!child->isPaintInvalidationContainer())
3678 child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
3682 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
3683 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
3685 } // namespace blink
3688 void showLayerTree(const blink::RenderLayer* layer)
3693 if (blink::LocalFrame* frame = layer->renderer()->frame()) {
3694 WTF::String output = externalRepresentation(frame, blink::RenderAsTextShowAllLayers | blink::RenderAsTextShowLayerNesting | blink::RenderAsTextShowCompositedLayers | blink::RenderAsTextShowAddresses | blink::RenderAsTextShowIDAndClass | blink::RenderAsTextDontUpdateLayout | blink::RenderAsTextShowLayoutState);
3695 fprintf(stderr, "%s\n", output.utf8().data());
3699 void showLayerTree(const blink::RenderObject* renderer)
3703 showLayerTree(renderer->enclosingLayer());