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_repainter(*renderer)
141 , m_clipper(*renderer)
143 updateStackingNode();
145 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
147 if (!renderer->slowFirstChild() && renderer->style()) {
148 m_visibleContentStatusDirty = false;
149 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
152 updateScrollableArea();
155 RenderLayer::~RenderLayer()
157 if (renderer()->frame() && renderer()->frame()->page()) {
158 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
159 scrollingCoordinator->willDestroyRenderLayer(this);
162 removeFilterInfoIfNeeded();
164 if (groupedMapping()) {
165 DisableCompositingQueryAsserts disabler;
166 groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this);
167 setGroupedMapping(0);
170 // Child layers will be deleted by their corresponding render objects, so
171 // we don't need to delete them ourselves.
173 clearCompositedLayerMapping(true);
175 if (m_reflectionInfo)
176 m_reflectionInfo->destroy();
179 String RenderLayer::debugName() const
181 if (isReflection()) {
182 ASSERT(m_reflectionInfo);
183 return m_reflectionInfo->debugName();
185 return renderer()->debugName();
188 RenderLayerCompositor* RenderLayer::compositor() const
190 if (!renderer()->view())
192 return renderer()->view()->compositor();
195 void RenderLayer::contentChanged(ContentChangeType changeType)
197 // updateLayerCompositingState will query compositingReasons for accelerated overflow scrolling.
198 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html
199 DisableCompositingQueryAsserts disabler;
201 if (changeType == CanvasChanged)
202 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
204 if (changeType == CanvasContextChanged) {
205 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
207 // Although we're missing test coverage, we need to call
208 // GraphicsLayer::setContentsToPlatformLayer with the new platform
209 // layer for this canvas.
210 // See http://crbug.com/349195
211 if (hasCompositedLayerMapping())
212 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
215 if (m_compositedLayerMapping)
216 m_compositedLayerMapping->contentChanged(changeType);
219 bool RenderLayer::paintsWithFilters() const
221 if (!renderer()->hasFilter())
224 // https://code.google.com/p/chromium/issues/detail?id=343759
225 DisableCompositingQueryAsserts disabler;
226 return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacking;
229 bool RenderLayer::requiresFullLayerImageForFilters() const
231 if (!paintsWithFilters())
233 FilterEffectRenderer* filter = filterRenderer();
234 return filter ? filter->hasFilterThatMovesPixels() : false;
237 LayoutSize RenderLayer::subpixelAccumulation() const
239 return m_subpixelAccumulation;
242 void RenderLayer::setSubpixelAccumulation(const LayoutSize& size)
244 m_subpixelAccumulation = size;
247 void RenderLayer::updateLayerPositionsAfterLayout()
249 TRACE_EVENT0("blink", "RenderLayer::updateLayerPositionsAfterLayout");
251 m_clipper.clearClipRectsIncludingDescendants();
252 updateLayerPositionRecursive();
255 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
256 // https://code.google.com/p/chromium/issues/detail?id=343756
257 DisableCompositingQueryAsserts disabler;
258 bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer();
259 updatePaginationRecursive(needsPaginationUpdate);
263 void RenderLayer::updateLayerPositionRecursive()
265 if (m_reflectionInfo)
266 m_reflectionInfo->reflection()->layout();
268 // FIXME: We should be able to remove this call because we don't care about
269 // any descendant-dependent flags, but code somewhere else is reading these
270 // flags and depending on us to update them.
271 updateDescendantDependentFlags();
273 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
274 child->updateLayerPositionRecursive();
277 void RenderLayer::updateHasSelfPaintingLayerDescendant() const
279 ASSERT(m_hasSelfPaintingLayerDescendantDirty);
281 m_hasSelfPaintingLayerDescendant = false;
283 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
284 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) {
285 m_hasSelfPaintingLayerDescendant = true;
290 m_hasSelfPaintingLayerDescendantDirty = false;
293 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
295 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
296 layer->m_hasSelfPaintingLayerDescendantDirty = true;
297 // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
298 // in this case, there is no need to dirty our ancestors further.
299 if (layer->isSelfPaintingLayer()) {
300 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->m_hasSelfPaintingLayerDescendant);
306 bool RenderLayer::scrollsWithViewport() const
308 return renderer()->style()->position() == FixedPosition && renderer()->containerForFixedPosition() == renderer()->view();
311 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
313 if (scrollsWithViewport() != other->scrollsWithViewport())
315 return ancestorScrollingLayer() != other->ancestorScrollingLayer();
318 void RenderLayer::updateTransformationMatrix()
321 RenderBox* box = renderBox();
323 m_transform->makeIdentity();
324 box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
325 makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositing());
329 void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle)
331 if (oldStyle && newStyle->transformDataEquivalent(*oldStyle))
334 // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
335 // so check style too.
336 bool hasTransform = renderer()->hasTransform() && newStyle->hasTransform();
337 bool had3DTransform = has3DTransform();
339 bool hadTransform = m_transform;
340 if (hasTransform != hadTransform) {
342 m_transform = adoptPtr(new TransformationMatrix);
346 // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
347 m_clipper.clearClipRectsIncludingDescendants();
348 } else if (hasTransform) {
349 m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
352 updateTransformationMatrix();
354 if (had3DTransform != has3DTransform())
355 dirty3DTransformedDescendantStatus();
358 static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer)
360 if (RenderObject* containingBlock = layer->renderer()->containingBlock())
361 return containingBlock->enclosingLayer();
365 RenderLayer* RenderLayer::renderingContextRoot()
367 RenderLayer* renderingContext = 0;
369 if (shouldPreserve3D())
370 renderingContext = this;
372 for (RenderLayer* current = enclosingLayerForContainingBlock(this); current && current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current))
373 renderingContext = current;
375 return renderingContext;
378 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
381 return TransformationMatrix();
383 // m_transform includes transform-origin, so we need to recompute the transform here.
384 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
385 RenderBox* box = renderBox();
386 TransformationMatrix currTransform;
387 box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
388 makeMatrixRenderable(currTransform, compositor()->hasAcceleratedCompositing());
389 return currTransform;
395 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
398 return TransformationMatrix();
400 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
401 TransformationMatrix matrix = *m_transform;
402 makeMatrixRenderable(matrix, false /* flatten 3d */);
409 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
411 const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
413 if (layer->renderer()->hasOverflowClip())
414 return const_cast<RenderLayer*>(layer);
416 layer = layer->parent();
421 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
423 RenderView* view = renderer->view();
424 RenderLayerModelObject* prevBlock = renderer;
425 RenderBlock* containingBlock;
426 for (containingBlock = renderer->containingBlock();
427 containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
428 containingBlock = containingBlock->containingBlock())
429 prevBlock = containingBlock;
431 // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
432 if (containingBlock != ancestorColumnsRenderer)
435 // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
436 if (prevBlock->isOutOfFlowPositioned())
439 // Otherwise we are paginated by the columns block.
443 bool RenderLayer::useRegionBasedColumns() const
445 return renderer()->document().regionBasedColumnsEnabled();
448 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate)
450 m_isPaginated = false;
451 m_enclosingPaginationLayer = 0;
453 if (useRegionBasedColumns() && renderer()->isRenderFlowThread())
454 needsPaginationUpdate = true;
456 if (needsPaginationUpdate)
459 if (renderer()->hasColumns())
460 needsPaginationUpdate = true;
462 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
463 child->updatePaginationRecursive(needsPaginationUpdate);
466 void RenderLayer::updatePagination()
468 if (compositingState() != NotComposited || !parent())
469 return; // FIXME: We will have to deal with paginated compositing layers someday.
470 // FIXME: For now the RenderView can't be paginated. Eventually printing will move to a model where it is though.
472 // The main difference between the paginated booleans for the old column code and the new column code
473 // is that each paginated layer has to paint on its own with the new code. There is no
474 // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on
475 // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and
476 // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
477 // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
478 // to that layer easily.
479 bool regionBasedColumnsUsed = useRegionBasedColumns();
480 if (regionBasedColumnsUsed && renderer()->isRenderFlowThread()) {
481 m_enclosingPaginationLayer = this;
485 if (m_stackingNode->isNormalFlowOnly()) {
486 if (regionBasedColumnsUsed) {
487 // Content inside a transform is not considered to be paginated, since we simply
488 // paint the transform multiple times in each column, so we don't have to use
489 // fragments for the transformed content.
490 m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
491 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
492 m_enclosingPaginationLayer = 0;
494 m_isPaginated = parent()->renderer()->hasColumns();
499 // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
500 // we find one, then we just check its pagination status.
501 if (regionBasedColumnsUsed) {
502 RenderView* view = renderer()->view();
503 RenderBlock* containingBlock;
504 for (containingBlock = renderer()->containingBlock();
505 containingBlock && containingBlock != view;
506 containingBlock = containingBlock->containingBlock()) {
507 if (containingBlock->hasLayer()) {
508 // Content inside a transform is not considered to be paginated, since we simply
509 // paint the transform multiple times in each column, so we don't have to use
510 // fragments for the transformed content.
511 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer();
512 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
513 m_enclosingPaginationLayer = 0;
520 // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
521 RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorStackingContextNode();
522 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
523 if (curr->renderer()->hasColumns()) {
524 m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
527 if (curr->stackingNode() == ancestorStackingContextNode)
532 LayoutPoint RenderLayer::positionFromPaintInvalidationContainer(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
534 if (!paintInvalidationContainer || !paintInvalidationContainer->layer()->groupedMapping())
535 return renderObject->positionFromPaintInvalidationContainer(paintInvalidationContainer, paintInvalidationState);
537 RenderLayerModelObject* transformedAncestor = paintInvalidationContainer->layer()->enclosingTransformedAncestor()->renderer();
538 LayoutPoint point = renderObject->positionFromPaintInvalidationContainer(paintInvalidationContainer, paintInvalidationState);
539 if (!transformedAncestor)
542 point = LayoutPoint(paintInvalidationContainer->localToContainerPoint(point, transformedAncestor));
543 point.moveBy(-paintInvalidationContainer->layer()->groupedMapping()->squashingOffsetFromTransformedAncestor());
547 void RenderLayer::mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect)
549 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
550 if (!paintInvalidationLayer->groupedMapping()) {
551 rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
555 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
556 if (!transformedAncestor)
559 // |repaintContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
560 // transformed ancestor.
561 rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect(rect), transformedAncestor).boundingBox());
563 rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
566 void RenderLayer::mapRectToPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState)
568 // FIXME: Passing paintInvalidationState directly to mapRectToPaintInvalidationBacking causes incorrect invalidations.
569 // Should avoid slowRectMapping by correctly adjusting paintInvalidationState. crbug.com/402983.
570 ForceHorriblySlowRectMapping slowRectMapping(paintInvalidationState);
571 ViewportConstrainedPosition viewportConstraint = renderObject->isRenderView() ? IsNotFixedPosition : ViewportConstraintDoesNotMatter;
573 if (!paintInvalidationContainer->layer()->groupedMapping()) {
574 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, viewportConstraint, paintInvalidationState);
578 // This code adjusts the repaint 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 repaint 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 repainting code structure.
582 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, viewportConstraint, paintInvalidationState);
584 RenderLayer::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);
591 LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer->renderer());
592 mapRectToPaintInvalidationBacking(paintInvalidationContainer->renderer(), paintInvalidationContainer->renderer(), rect, paintInvalidationState);
596 void RenderLayer::dirtyVisibleContentStatus()
598 m_visibleContentStatusDirty = true;
600 parent()->dirtyAncestorChainVisibleDescendantStatus();
603 void RenderLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility)
605 if (m_visibleContentStatusDirty)
607 if (hasVisibleContent() == (visibility == VISIBLE))
609 dirtyVisibleContentStatus();
612 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
614 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
615 if (layer->m_visibleDescendantStatusDirty)
618 layer->m_visibleDescendantStatusDirty = true;
622 // FIXME: this is quite brute-force. We could be more efficient if we were to
623 // track state and update it as appropriate as changes are made in the Render tree.
624 void RenderLayer::updateScrollingStateAfterCompositingChange()
626 TRACE_EVENT0("blink", "RenderLayer::updateScrollingStateAfterCompositingChange");
627 m_hasVisibleNonLayerContent = false;
628 for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()) {
629 if (!r->hasLayer()) {
630 m_hasVisibleNonLayerContent = true;
635 m_hasNonCompositedChild = false;
636 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
637 if (child->compositingState() == NotComposited || child->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
638 m_hasNonCompositedChild = true;
644 // The descendant-dependent flags system is badly broken because we clean dirty
645 // bits in upward tree walks, which means we need to call updateDescendantDependentFlags
646 // at every node in the tree to fully clean all the dirty bits. While we'll in
647 // the process of fixing this issue, updateDescendantDependentFlagsForEntireSubtree
648 // provides a big hammer for actually cleaning all the dirty bits in a subtree.
650 // FIXME: Remove this function once the descendant-dependent flags system keeps
651 // its dirty bits scoped to subtrees.
652 void RenderLayer::updateDescendantDependentFlagsForEntireSubtree()
654 updateDescendantDependentFlags();
656 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
657 child->updateDescendantDependentFlagsForEntireSubtree();
660 void RenderLayer::updateDescendantDependentFlags()
662 if (m_visibleDescendantStatusDirty) {
663 m_hasVisibleDescendant = false;
665 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
666 child->updateDescendantDependentFlags();
668 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
669 m_hasVisibleDescendant = true;
674 m_visibleDescendantStatusDirty = false;
677 if (m_visibleContentStatusDirty) {
678 bool previouslyHasVisibleContent = m_hasVisibleContent;
679 if (renderer()->style()->visibility() == VISIBLE)
680 m_hasVisibleContent = true;
682 // layer may be hidden but still have some visible content, check for this
683 m_hasVisibleContent = false;
684 RenderObject* r = renderer()->slowFirstChild();
686 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
687 m_hasVisibleContent = true;
690 RenderObject* rendererFirstChild = r->slowFirstChild();
691 if (rendererFirstChild && !r->hasLayer())
692 r = rendererFirstChild;
693 else if (r->nextSibling())
694 r = r->nextSibling();
700 } while (r && !r->nextSibling());
702 r = r->nextSibling();
706 m_visibleContentStatusDirty = false;
708 if (hasVisibleContent() != previouslyHasVisibleContent) {
709 setNeedsCompositingInputsUpdate();
710 // We need to tell m_renderer to recheck its rect because we
711 // pretend that invisible RenderObjects have 0x0 rects. Changing
712 // visibility therefore changes our rect and we need to visit
713 // this RenderObject during the invalidateTreeIfNeeded walk.
714 m_renderer->setMayNeedPaintInvalidation(true);
719 void RenderLayer::dirty3DTransformedDescendantStatus()
721 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNode();
725 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
727 // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
728 // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
729 while (stackingNode && stackingNode->layer()->preserves3D()) {
730 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
731 stackingNode = stackingNode->ancestorStackingContextNode();
735 // Return true if this layer or any preserve-3d descendants have 3d.
736 bool RenderLayer::update3DTransformedDescendantStatus()
738 if (m_3DTransformedDescendantStatusDirty) {
739 m_has3DTransformedDescendant = false;
741 m_stackingNode->updateZOrderLists();
743 // Transformed or preserve-3d descendants can only be in the z-order lists, not
744 // in the normal flow list, so we only need to check those.
745 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren);
746 while (RenderLayerStackingNode* node = iterator.next())
747 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDescendantStatus();
749 m_3DTransformedDescendantStatusDirty = false;
752 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
753 // the m_has3DTransformedDescendant set.
755 return has3DTransform() || m_has3DTransformedDescendant;
757 return has3DTransform();
760 IntSize RenderLayer::size() const
762 if (renderer()->isInline() && renderer()->isRenderInline())
763 return toRenderInline(renderer())->linesBoundingBox().size();
765 // FIXME: Is snapping the size really needed here?
766 if (RenderBox* box = renderBox())
767 return pixelSnappedIntSize(box->size(), box->location());
772 LayoutPoint RenderLayer::location() const
774 LayoutPoint localPoint;
775 LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
777 if (renderer()->isInline() && renderer()->isRenderInline()) {
778 RenderInline* inlineFlow = toRenderInline(renderer());
779 IntRect lineBox = inlineFlow->linesBoundingBox();
780 inlineBoundingBoxOffset = toSize(lineBox.location());
781 localPoint += inlineBoundingBoxOffset;
782 } else if (RenderBox* box = renderBox()) {
783 localPoint += box->topLeftLocationOffset();
786 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) {
787 // We must adjust our position by walking up the render tree looking for the
788 // nearest enclosing object with a layer.
789 RenderObject* curr = renderer()->parent();
790 while (curr && !curr->hasLayer()) {
791 if (curr->isBox() && !curr->isTableRow()) {
792 // Rows and cells share the same coordinate space (that of the section).
793 // Omit them when computing our xpos/ypos.
794 localPoint += toRenderBox(curr)->topLeftLocationOffset();
796 curr = curr->parent();
798 if (curr->isBox() && curr->isTableRow()) {
799 // Put ourselves into the row coordinate space.
800 localPoint -= toRenderBox(curr)->topLeftLocationOffset();
804 // Subtract our parent's scroll offset.
805 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
806 RenderLayer* positionedParent = enclosingPositionedAncestor();
808 // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
809 if (positionedParent->renderer()->hasOverflowClip()) {
810 LayoutSize offset = positionedParent->renderBox()->scrolledContentOffset();
811 localPoint -= offset;
814 if (positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
815 LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer()));
816 localPoint += offset;
818 } else if (parent()) {
819 // FIXME: This code is very wrong. The compositing system doesn't
820 // understand columns and we're hacking around that fact by faking
821 // the position of the RenderLayers when we think we'll end up being
822 // composited. Hopefully we'll be able to unwind this hack when we
823 // implement multi-column using regions.
824 if (hasStyleDeterminedDirectCompositingReasons()) {
825 // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
826 // They won't split across columns properly.
827 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isDocumentElement() && renderer()->view()->hasColumns())
828 localPoint += renderer()->view()->columnOffset(localPoint);
830 localPoint += parent()->renderer()->columnOffset(localPoint);
833 if (parent()->renderer()->hasOverflowClip()) {
834 IntSize scrollOffset = parent()->renderBox()->scrolledContentOffset();
835 localPoint -= scrollOffset;
839 localPoint.move(offsetForInFlowPosition());
841 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
842 localPoint -= inlineBoundingBoxOffset;
847 const LayoutSize RenderLayer::offsetForInFlowPosition() const
849 return renderer()->isRelPositioned() ? toRenderBoxModelObject(renderer())->offsetForInFlowPosition() : LayoutSize();
852 TransformationMatrix RenderLayer::perspectiveTransform() const
854 if (!renderer()->hasTransform())
855 return TransformationMatrix();
857 RenderStyle* style = renderer()->style();
858 if (!style->hasPerspective())
859 return TransformationMatrix();
861 // Maybe fetch the perspective from the backing?
862 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
863 const float boxWidth = borderBox.width();
864 const float boxHeight = borderBox.height();
866 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth);
867 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight);
869 // A perspective origin of 0,0 makes the vanishing point in the center of the element.
870 // We want it to be in the top-left, so subtract half the height and width.
871 perspectiveOriginX -= boxWidth / 2.0f;
872 perspectiveOriginY -= boxHeight / 2.0f;
874 TransformationMatrix t;
875 t.translate(perspectiveOriginX, perspectiveOriginY);
876 t.applyPerspective(style->perspective());
877 t.translate(-perspectiveOriginX, -perspectiveOriginY);
882 FloatPoint RenderLayer::perspectiveOrigin() const
884 if (!renderer()->hasTransform())
887 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
888 RenderStyle* style = renderer()->style();
890 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.height().toFloat()));
893 static inline bool isFixedPositionedContainer(RenderLayer* layer)
895 return layer->isRootLayer() || layer->hasTransform();
898 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
900 RenderLayer* curr = parent();
901 while (curr && !curr->isPositionedContainer())
902 curr = curr->parent();
907 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
909 RenderLayer* curr = parent();
910 while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransform())
911 curr = curr->parent();
916 LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const
918 const AncestorDependentCompositingInputs& properties = ancestorDependentCompositingInputs();
920 TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
921 // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip are correct.
922 renderer()->mapLocalToContainer(properties.transformAncestor ? properties.transformAncestor->renderer() : 0, transformState, ApplyContainerFlip);
923 transformState.flatten();
924 return LayoutPoint(transformState.lastPlanarPoint());
927 const RenderLayer* RenderLayer::compositingContainer() const
929 if (stackingNode()->isNormalFlowOnly())
931 if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContextNode())
932 return ancestorStackingNode->layer();
936 bool RenderLayer::isPaintInvalidationContainer() const
938 return compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking;
941 // Note: enclosingCompositingLayer does not include squashed layers. Compositing stacking children of squashed layers
942 // receive graphics layers that are parented to the compositing ancestor of the squashed layer.
943 RenderLayer* RenderLayer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot includeSelf) const
945 ASSERT(isAllowedToQueryCompositingState());
947 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
948 return const_cast<RenderLayer*>(this);
950 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
951 if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking)
952 return const_cast<RenderLayer*>(curr);
958 // Return the enclosingCompositedLayerForPaintInvalidation for the given RenderLayer
959 // including crossing frame boundaries.
960 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const
962 const RenderLayer* layer = this;
963 RenderLayer* compositedLayer = 0;
964 while (!compositedLayer) {
965 compositedLayer = layer->enclosingLayerForPaintInvalidation();
966 if (!compositedLayer) {
967 RenderObject* owner = layer->renderer()->frame()->ownerRenderer();
970 layer = owner->enclosingLayer();
973 return compositedLayer;
976 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidation() const
978 ASSERT(isAllowedToQueryCompositingState());
980 if (isPaintInvalidationContainer())
981 return const_cast<RenderLayer*>(this);
983 for (const RenderLayer* curr = parent(); curr; curr = curr->parent()) {
984 if (curr->isPaintInvalidationContainer())
985 return const_cast<RenderLayer*>(curr);
991 RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
993 const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
994 for (; curr; curr = curr->parent()) {
995 if (curr->requiresFullLayerImageForFilters())
996 return const_cast<RenderLayer*>(curr);
1002 void RenderLayer::setNeedsCompositingInputsUpdate()
1004 m_needsAncestorDependentCompositingInputsUpdate = true;
1005 m_needsDescendantDependentCompositingInputsUpdate = true;
1007 for (RenderLayer* current = this; current && !current->m_childNeedsCompositingInputsUpdate; current = current->parent())
1008 current->m_childNeedsCompositingInputsUpdate = true;
1010 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
1013 void RenderLayer::updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs& compositingInputs)
1015 m_ancestorDependentCompositingInputs = compositingInputs;
1016 m_needsAncestorDependentCompositingInputsUpdate = false;
1019 void RenderLayer::updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs& compositingInputs)
1021 m_descendantDependentCompositingInputs = compositingInputs;
1022 m_needsDescendantDependentCompositingInputsUpdate = false;
1025 void RenderLayer::didUpdateCompositingInputs()
1027 ASSERT(!needsCompositingInputsUpdate());
1028 m_childNeedsCompositingInputsUpdate = false;
1029 if (m_scrollableArea)
1030 m_scrollableArea->updateNeedsCompositedScrolling();
1033 void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingReasons mask)
1035 if ((compositingReasons() & mask) == (reasons & mask))
1037 m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask);
1040 void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant)
1042 if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescendant))
1045 m_hasCompositingDescendant = hasCompositingDescendant;
1047 if (hasCompositedLayerMapping())
1048 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
1051 void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDescendants)
1053 if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsolateCompositedDescendants))
1056 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants;
1058 if (hasCompositedLayerMapping())
1059 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
1062 bool RenderLayer::hasAncestorWithFilterOutsets() const
1064 for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1065 RenderLayerModelObject* renderer = curr->renderer();
1066 if (renderer->style()->hasFilterOutsets())
1072 RenderLayer* RenderLayer::transparentPaintingAncestor()
1074 if (hasCompositedLayerMapping())
1077 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1078 if (curr->hasCompositedLayerMapping())
1080 if (curr->isTransparent())
1086 enum TransparencyClipBoxBehavior {
1087 PaintingTransparencyClipBox,
1088 HitTestingTransparencyClipBox
1091 enum TransparencyClipBoxMode {
1092 DescendantsOfTransparencyClipBox,
1093 RootOfTransparencyClipBox
1096 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0);
1098 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1099 TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1101 // If we have a mask, then the clip is limited to the border box area (and there is
1102 // no need to examine child layers).
1103 if (!layer->renderer()->hasMask()) {
1104 // Note: we don't have to walk z-order lists since transparent elements always establish
1105 // a stacking container. This means we can just walk the layer tree directly.
1106 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1107 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
1108 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior));
1112 // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire
1113 // current transparencyClipBox to catch all child layers.
1114 // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1115 // size into the parent layer.
1116 if (layer->renderer()->hasReflection()) {
1118 layer->convertToLayerCoords(rootLayer, delta);
1119 clipRect.move(-delta.x(), -delta.y());
1120 clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1121 clipRect.moveBy(delta);
1125 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1126 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1128 // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1129 // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
1130 // would be better to respect clips.
1132 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
1133 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) {
1134 // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1135 // the transformed layer and all of its children.
1136 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
1137 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1139 layer->convertToLayerCoords(rootLayerForTransform, delta);
1141 delta.move(subPixelAccumulation);
1142 IntPoint pixelSnappedDelta = roundedIntPoint(delta);
1143 TransformationMatrix transform;
1144 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
1145 transform = transform * *layer->transform();
1147 // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1148 // paints unfragmented.
1149 LayoutRect clipRect = layer->physicalBoundingBox(layer);
1150 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior);
1151 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1152 LayoutRect result = transform.mapRect(clipRect);
1153 if (!paginationLayer)
1156 // We have to break up the transformed extent across our columns.
1157 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1158 // get our true bounding box.
1159 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1160 result = enclosingFlowThread->fragmentsBoundingBox(result);
1162 LayoutPoint rootLayerDelta;
1163 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1164 result.moveBy(rootLayerDelta);
1168 LayoutRect clipRect = layer->physicalBoundingBox(rootLayer);
1169 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior);
1170 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1171 clipRect.move(subPixelAccumulation);
1175 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1177 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect);
1180 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1182 bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && hasDescendantWithBlendMode();
1183 if ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency)
1186 RenderLayer* ancestor = transparentPaintingAncestor();
1188 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
1190 if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) {
1191 m_usedTransparency = true;
1193 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
1194 context->clip(clipRect);
1196 if (paintsWithBlendMode())
1197 context->setCompositeOperation(context->compositeOperation(), m_renderer->style()->blendMode());
1199 context->beginTransparencyLayer(renderer()->opacity());
1201 if (paintsWithBlendMode())
1202 context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal);
1203 #ifdef REVEAL_TRANSPARENCY_LAYERS
1204 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
1205 context->fillRect(clipRect);
1210 void* RenderLayer::operator new(size_t sz)
1212 return partitionAlloc(Partitions::getRenderingPartition(), sz);
1215 void RenderLayer::operator delete(void* ptr)
1220 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1222 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1224 child->setPreviousSibling(prevSibling);
1225 prevSibling->setNextSibling(child);
1226 ASSERT(prevSibling != child);
1228 setFirstChild(child);
1231 beforeChild->setPreviousSibling(child);
1232 child->setNextSibling(beforeChild);
1233 ASSERT(beforeChild != child);
1235 setLastChild(child);
1237 child->m_parent = this;
1239 setNeedsCompositingInputsUpdate();
1241 if (child->stackingNode()->isNormalFlowOnly())
1242 m_stackingNode->dirtyNormalFlowList();
1244 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) {
1245 // Dirty the z-order list in which we are contained. The ancestorStackingContextNode() can be null in the
1246 // case where we're building up generated content layers. This is ok, since the lists will start
1247 // off dirty in that case anyway.
1248 child->stackingNode()->dirtyStackingContextZOrderLists();
1251 dirtyAncestorChainVisibleDescendantStatus();
1252 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1254 child->updateDescendantDependentFlags();
1257 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1259 if (oldChild->previousSibling())
1260 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1261 if (oldChild->nextSibling())
1262 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1264 if (m_first == oldChild)
1265 m_first = oldChild->nextSibling();
1266 if (m_last == oldChild)
1267 m_last = oldChild->previousSibling();
1269 if (oldChild->stackingNode()->isNormalFlowOnly())
1270 m_stackingNode->dirtyNormalFlowList();
1271 if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) {
1272 // Dirty the z-order list in which we are contained. When called via the
1273 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1274 // from the main layer tree, so we need to null-check the
1275 // |stackingContext| value.
1276 oldChild->stackingNode()->dirtyStackingContextZOrderLists();
1279 if (renderer()->style()->visibility() != VISIBLE)
1280 dirtyVisibleContentStatus();
1282 oldChild->setPreviousSibling(0);
1283 oldChild->setNextSibling(0);
1284 oldChild->m_parent = 0;
1286 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1288 oldChild->updateDescendantDependentFlags();
1290 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1291 dirtyAncestorChainVisibleDescendantStatus();
1296 void RenderLayer::removeOnlyThisLayer()
1301 m_clipper.clearClipRectsIncludingDescendants();
1302 paintInvalidator().paintInvalidationIncludingNonCompositingDescendants();
1304 RenderLayer* nextSib = nextSibling();
1306 // Remove the child reflection layer before moving other child layers.
1307 // The reflection layer should not be moved to the parent.
1308 if (m_reflectionInfo)
1309 removeChild(m_reflectionInfo->reflectionLayer());
1311 // Now walk our kids and reattach them to our parent.
1312 RenderLayer* current = m_first;
1314 RenderLayer* next = current->nextSibling();
1315 removeChild(current);
1316 m_parent->addChild(current, nextSib);
1318 current->renderer()->setShouldDoFullPaintInvalidation(true);
1319 // FIXME: We should call a specialized version of this function.
1320 current->updateLayerPositionsAfterLayout();
1324 // Remove us from the parent.
1325 m_parent->removeChild(this);
1326 m_renderer->destroyLayer();
1329 void RenderLayer::insertOnlyThisLayer()
1331 if (!m_parent && renderer()->parent()) {
1332 // We need to connect ourselves when our renderer() has a parent.
1333 // Find our enclosingLayer and add ourselves.
1334 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
1335 ASSERT(parentLayer);
1336 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
1337 parentLayer->addChild(this, beforeChild);
1340 // Remove all descendant layers from the hierarchy and add them to the new position.
1341 for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->nextSibling())
1342 curr->moveLayers(m_parent, this);
1344 // Clear out all the clip rects.
1345 m_clipper.clearClipRectsIncludingDescendants();
1348 // Returns the layer reached on the walk up towards the ancestor.
1349 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
1351 ASSERT(ancestorLayer != layer);
1353 const RenderLayerModelObject* renderer = layer->renderer();
1354 EPosition position = renderer->style()->position();
1356 // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great.
1357 RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer->flowThreadContainingBlock() : 0;
1358 if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
1359 fixedFlowThreadContainer = 0;
1361 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1362 // may need to be revisited in a future patch.
1363 // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1364 // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be
1365 // positioned in a completely different place in the viewport (RenderView).
1366 if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
1367 // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1368 // localToAbsolute() on the RenderView.
1369 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed);
1370 location += LayoutSize(absPos.x(), absPos.y());
1371 return ancestorLayer;
1374 // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1375 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1376 // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1377 if (position == FixedPosition && !fixedFlowThreadContainer) {
1378 // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1379 // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1380 // so we should always find the ancestor at or before we find the fixed position container.
1381 RenderLayer* fixedPositionContainerLayer = 0;
1382 bool foundAncestor = false;
1383 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1384 if (currLayer == ancestorLayer)
1385 foundAncestor = true;
1387 if (isFixedPositionedContainer(currLayer)) {
1388 fixedPositionContainerLayer = currLayer;
1389 ASSERT_UNUSED(foundAncestor, foundAncestor);
1394 ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1396 if (fixedPositionContainerLayer != ancestorLayer) {
1397 LayoutPoint fixedContainerCoords;
1398 layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1400 LayoutPoint ancestorCoords;
1401 ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1403 location += (fixedContainerCoords - ancestorCoords);
1405 location += toSize(layer->location());
1407 return ancestorLayer;
1410 RenderLayer* parentLayer;
1411 if (position == AbsolutePosition || position == FixedPosition) {
1412 // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
1413 parentLayer = layer->parent();
1414 bool foundAncestorFirst = false;
1415 while (parentLayer) {
1416 // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
1417 // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
1418 // we are bailing out before reaching root layer.
1419 if (parentLayer->isPositionedContainer())
1422 if (parentLayer == ancestorLayer) {
1423 foundAncestorFirst = true;
1427 parentLayer = parentLayer->parent();
1430 // We should not reach RenderView layer past the RenderFlowThread layer for any
1431 // children of the RenderFlowThread.
1432 ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer());
1434 if (foundAncestorFirst) {
1435 // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
1436 // to enclosingPositionedAncestor and subtract.
1437 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
1439 LayoutPoint thisCoords;
1440 layer->convertToLayerCoords(positionedAncestor, thisCoords);
1442 LayoutPoint ancestorCoords;
1443 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
1445 location += (thisCoords - ancestorCoords);
1446 return ancestorLayer;
1449 parentLayer = layer->parent();
1454 location += toSize(layer->location());
1458 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
1460 if (ancestorLayer == this)
1463 const RenderLayer* currLayer = this;
1464 while (currLayer && currLayer != ancestorLayer)
1465 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location);
1468 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
1471 convertToLayerCoords(ancestorLayer, delta);
1472 rect.move(-delta.x(), -delta.y());
1475 void RenderLayer::didUpdateNeedsCompositedScrolling()
1477 updateSelfPaintingLayer();
1480 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle)
1482 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle));
1483 if (renderer()->hasReflection()) {
1484 if (!m_reflectionInfo)
1485 m_reflectionInfo = adoptPtrWillBeNoop(new RenderLayerReflectionInfo(*renderBox()));
1486 m_reflectionInfo->updateAfterStyleChange(oldStyle);
1487 } else if (m_reflectionInfo) {
1488 m_reflectionInfo->destroy();
1489 m_reflectionInfo = nullptr;
1493 void RenderLayer::updateStackingNode()
1495 if (requiresStackingNode())
1496 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this));
1498 m_stackingNode = nullptr;
1501 void RenderLayer::updateScrollableArea()
1503 if (requiresScrollableArea())
1504 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this));
1506 m_scrollableArea = nullptr;
1509 bool RenderLayer::hasOverflowControls() const
1511 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE);
1514 void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, PaintLayerFlags paintFlags)
1516 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
1517 if (shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags))
1518 paintLayer(context, paintingInfo, paintFlags);
1521 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
1523 if (!m_containsDirtyOverlayScrollbars)
1526 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
1527 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars);
1529 m_containsDirtyOverlayScrollbars = false;
1532 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
1534 if (startLayer == endLayer)
1537 RenderView* view = startLayer->renderer()->view();
1538 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) {
1539 if (currentBlock->layer() == endLayer)
1546 void RenderLayer::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect,
1547 PaintLayerFlags paintFlags, BorderRadiusClippingRule rule)
1549 if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius())
1552 context->clip(pixelSnappedIntRect(clipRect.rect()));
1554 if (!clipRect.hasRadius())
1557 // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
1558 // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
1559 // containing block chain so we check that also.
1560 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
1561 // Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not
1562 // want to apply a border-radius clip to the layer contents itself, because that would require re-rastering
1563 // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
1564 // that it can in turn clip the scrolled contents in the compositor.
1565 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
1568 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
1570 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
1571 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
1574 if (layer == localPaintingInfo.rootLayer)
1579 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
1581 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
1586 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
1588 // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
1589 // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
1590 // will do a full repaint().
1591 if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isDocumentElement())
1597 static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags)
1599 return layer->renderer()->isDocumentElement() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
1602 static ShouldRespectOverflowClip shouldRespectOverflowClip(PaintLayerFlags paintFlags, const RenderObject* renderer)
1604 return (paintFlags & PaintLayerPaintingOverflowContents || (paintFlags & PaintLayerPaintingChildClippingMaskPhase && renderer->hasClipPath())) ? IgnoreOverflowClip : RespectOverflowClip;
1607 void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1609 // https://code.google.com/p/chromium/issues/detail?id=343772
1610 DisableCompositingQueryAsserts disabler;
1612 if (compositingState() != NotComposited) {
1613 if (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers) {
1614 // FIXME: ok, but what about PaintBehaviorFlattenCompositingLayers? That's for printing.
1615 // FIXME: why isn't the code here global, as opposed to being set on each paintLayer() call?
1616 paintFlags |= PaintLayerUncachedClipRects;
1620 // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
1621 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
1624 if (shouldSuppressPaintingLayer(this))
1627 // If this layer is totally invisible then there is nothing to paint.
1628 if (!renderer()->opacity())
1631 if (paintsWithTransparency(paintingInfo.paintBehavior))
1632 paintFlags |= PaintLayerHaveTransparency;
1634 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice.
1635 if (paintsWithTransform(paintingInfo.paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
1636 TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior);
1637 // If the transform can't be inverted, then don't paint anything.
1638 if (!layerTransform.isInvertible())
1641 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
1642 // layer from the parent now, assuming there is a parent
1643 if (paintFlags & PaintLayerHaveTransparency) {
1645 parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
1647 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
1650 if (enclosingPaginationLayer()) {
1651 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags);
1655 // Make sure the parent's clip rects have been calculated.
1656 ClipRect clipRect = paintingInfo.paintDirtyRect;
1658 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize);
1659 if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip)
1660 clipRectsContext.setIgnoreOverflowClip();
1661 clipRect = clipper().backgroundClipRect(clipRectsContext);
1662 clipRect.intersect(paintingInfo.paintDirtyRect);
1664 // Push the parent coordinate space's clip.
1665 parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
1668 paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
1670 // Restore the clip.
1672 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
1677 paintLayerContentsAndReflection(context, paintingInfo, paintFlags);
1680 void RenderLayer::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1682 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1684 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
1686 // Paint the reflection first if we have one.
1687 if (m_reflectionInfo)
1688 m_reflectionInfo->paint(context, paintingInfo, localPaintFlags | PaintLayerPaintingReflection);
1690 localPaintFlags |= PaintLayerPaintingCompositingAllPhases;
1691 paintLayerContents(context, paintingInfo, localPaintFlags);
1694 void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1696 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1697 ASSERT(!(paintFlags & PaintLayerAppliedTransform));
1699 bool haveTransparency = paintFlags & PaintLayerHaveTransparency;
1700 bool isSelfPaintingLayer = this->isSelfPaintingLayer();
1701 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
1702 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase;
1703 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase;
1704 bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase;
1705 bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents;
1706 // Outline always needs to be painted even if we have no visible content. Also,
1707 // the outline is painted in the background phase during composited scrolling.
1708 // If it were painted in the foreground phase, it would move with the scrolled
1709 // content. When not composited scrolling, the outline is painted in the
1710 // foreground phase. Since scrolled contents are moved by repainting in this
1711 // case, the outline won't get 'dragged along'.
1712 bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
1713 && ((isPaintingScrollingContent && isPaintingCompositedBackground)
1714 || (!isPaintingScrollingContent && isPaintingCompositedForeground));
1715 bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
1717 float deviceScaleFactor = blink::deviceScaleFactor(renderer()->frame());
1718 context->setDeviceScaleFactor(deviceScaleFactor);
1720 GraphicsContext* transparencyLayerContext = context;
1722 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isDocumentElement())
1725 // Ensure our lists are up-to-date.
1726 m_stackingNode->updateLayerListsIfNeeded();
1728 LayoutPoint offsetFromRoot;
1729 convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
1731 if (compositingState() == PaintsIntoOwnBacking)
1732 offsetFromRoot.move(subpixelAccumulation());
1734 LayoutRect rootRelativeBounds;
1735 bool rootRelativeBoundsComputed = false;
1737 // Apply clip-path to context.
1738 GraphicsContextStateSaver clipStateSaver(*context, false);
1739 RenderStyle* style = renderer()->style();
1740 RenderSVGResourceClipper* resourceClipper = 0;
1741 ClipperContext clipperContext;
1743 // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container.
1744 // It must, however, still be applied to the mask layer, so that the compositor can properly mask the
1745 // scrolling contents and scrollbars.
1746 if (renderer()->hasClipPath() && style && (!needsCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase)) {
1747 ASSERT(style->clipPath());
1748 if (style->clipPath()->type() == ClipPathOperation::SHAPE) {
1749 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath());
1750 if (clipPath->isValid()) {
1751 clipStateSaver.save();
1753 if (!rootRelativeBoundsComputed) {
1754 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1755 rootRelativeBoundsComputed = true;
1758 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule());
1760 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) {
1761 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath());
1762 Document& document = renderer()->document();
1763 // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
1764 Element* element = document.getElementById(referenceClipPathOperation->fragment());
1765 if (isSVGClipPathElement(element) && element->renderer()) {
1766 // FIXME: Saving at this point is not required in the 'mask'-
1767 // case, or if the clip ends up empty.
1768 clipStateSaver.save();
1769 if (!rootRelativeBoundsComputed) {
1770 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1771 rootRelativeBoundsComputed = true;
1774 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer()));
1775 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativeBounds,
1776 paintingInfo.paintDirtyRect, context, clipperContext)) {
1777 // No need to post-apply the clipper if this failed.
1778 resourceClipper = 0;
1784 // Blending operations must be performed only with the nearest ancestor stacking context.
1785 // Note that there is no need to create a transparency layer if we're painting the root.
1786 bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && hasDescendantWithBlendMode();
1788 if (createTransparencyLayerForBlendMode)
1789 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
1791 LayerPaintingInfo localPaintingInfo(paintingInfo);
1792 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
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)) {
1800 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
1801 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
1802 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that
1803 // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method.
1804 context = filterPainter.beginFilterEffect(context);
1806 // Check that we didn't fail to allocate the graphics context for the offscreen buffer.
1807 if (filterPainter.hasStartedFilterEffect()) {
1808 localPaintingInfo.paintDirtyRect = filterPainter.repaintRect();
1809 // If the filter needs the full source image, we need to avoid using the clip rectangles.
1810 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
1811 // Note that we will still apply the clipping on the final rendering of the filter.
1812 localPaintingInfo.clipToDirtyRect = !filterRenderer()->hasFilterThatMovesPixels();
1817 if (filterPainter.hasStartedFilterEffect() && haveTransparency) {
1818 // 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.
1819 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
1822 // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
1823 // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
1824 // Else, our renderer tree may or may not contain the painting root, so we pass that root along
1825 // so it will be tested against as we descend through the renderers.
1826 RenderObject* paintingRootForRenderer = 0;
1827 if (localPaintingInfo.paintingRoot && !renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
1828 paintingRootForRenderer = localPaintingInfo.paintingRoot;
1830 ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText));
1831 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
1833 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
1834 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground);
1835 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent;
1836 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground;
1837 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars;
1838 bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly;
1839 bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly;
1841 PaintBehavior paintBehavior = PaintBehaviorNormal;
1842 if (paintFlags & PaintLayerPaintingSkipRootBackground)
1843 paintBehavior |= PaintBehaviorSkipRootBackground;
1844 else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
1845 paintBehavior |= PaintBehaviorRootBackgroundOnly;
1847 LayerFragments layerFragments;
1848 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
1849 // 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
1850 // fragment should paint.
1851 collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
1852 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
1853 shouldRespectOverflowClip(paintFlags, renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
1854 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
1857 if (shouldPaintBackground) {
1858 paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
1859 localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
1862 if (shouldPaintNegZOrderList)
1863 paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags);
1865 if (shouldPaintOwnContents) {
1866 paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
1867 localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags);
1870 if (shouldPaintOutline)
1871 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
1873 if (shouldPaintNormalFlowAndPosZOrderLists)
1874 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags);
1876 if (shouldPaintOverlayScrollbars)
1877 paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
1879 if (filterPainter.hasStartedFilterEffect()) {
1880 // Apply the correct clipping (ie. overflow: hidden).
1881 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
1882 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
1883 clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect, paintFlags);
1884 context = filterPainter.applyFilterEffect();
1885 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
1888 // Make sure that we now use the original transparency context.
1889 ASSERT(transparencyLayerContext == context);
1891 if (shouldPaintMask)
1892 paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
1894 if (shouldPaintClippingMask) {
1895 // Paint the border radius mask for the fragments.
1896 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
1899 // End our transparency layer
1900 if ((haveTransparency || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency && !(m_reflectionInfo && m_reflectionInfo->isPaintingInsideReflection())) {
1901 context->endLayer();
1903 m_usedTransparency = false;
1906 if (resourceClipper)
1907 resourceClipper->postApplyStatefulResource(renderer(), context, clipperContext);
1910 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset)
1912 // This involves subtracting out the position of the layer in our current coordinate space, but preserving
1913 // the accumulated error for sub-pixel layout.
1915 convertToLayerCoords(paintingInfo.rootLayer, delta);
1916 delta.moveBy(translationOffset);
1917 TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
1918 IntPoint roundedDelta = roundedIntPoint(delta);
1919 transform.translateRight(roundedDelta.x(), roundedDelta.y());
1920 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
1922 // Apply the transform.
1923 GraphicsContextStateSaver stateSaver(*context, false);
1924 if (!transform.isIdentity()) {
1926 context->concatCTM(transform.toAffineTransform());
1929 // Now do a paint with the root layer shifted to be us.
1930 LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior,
1931 adjustedSubPixelAccumulation, paintingInfo.paintingRoot);
1932 paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
1935 bool RenderLayer::shouldPaintLayerInSoftwareMode(const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1937 DisableCompositingQueryAsserts disabler;
1939 return compositingState() == NotComposited
1940 || compositingState() == HasOwnBackingButPaintsIntoAncestor
1941 || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)
1942 || ((paintFlags & PaintLayerPaintingReflection) && !has3DTransform())
1943 || paintForFixedRootBackground(this, paintFlags);
1946 void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1948 if (!hasSelfPaintingLayerDescendant())
1952 LayerListMutationDetector mutationChecker(m_stackingNode.get());
1955 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit);
1956 while (RenderLayerStackingNode* child = iterator.next()) {
1957 RenderLayer* childLayer = child->layer();
1958 // If this RenderLayer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents()
1959 // and CompositedLayerMapping::doPaintTask().
1960 if (!childLayer->shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags))
1963 if (!childLayer->isPaginated())
1964 childLayer->paintLayer(context, paintingInfo, paintFlags);
1966 paintPaginatedChildLayer(childLayer, context, paintingInfo, paintFlags);
1970 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
1971 ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
1972 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
1974 if (!enclosingPaginationLayer() || hasTransform()) {
1975 // For unpaginated layers, there is only one fragment.
1976 LayerFragment fragment;
1977 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy, subPixelAccumulation);
1978 if (respectOverflowClip == IgnoreOverflowClip)
1979 clipRectsContext.setIgnoreOverflowClip();
1980 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
1981 fragments.append(fragment);
1985 // Compute our offset within the enclosing pagination layer.
1986 LayoutPoint offsetWithinPaginatedLayer;
1987 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer);
1989 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
1990 // 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.
1991 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
1992 if (respectOverflowClip == IgnoreOverflowClip)
1993 paginationClipRectsContext.setIgnoreOverflowClip();
1994 LayoutRect layerBoundsInFlowThread;
1995 ClipRect backgroundRectInFlowThread;
1996 ClipRect foregroundRectInFlowThread;
1997 ClipRect outlineRectInFlowThread;
1998 clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
1999 outlineRectInFlowThread, &offsetWithinPaginatedLayer);
2001 // Take our bounding box within the flow thread and clip it.
2002 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer);
2003 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
2005 // Shift the dirty rect into flow thread coordinates.
2006 LayoutPoint offsetOfPaginationLayerFromRoot;
2007 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
2008 LayoutRect dirtyRectInFlowThread(dirtyRect);
2009 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot);
2011 // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
2012 // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
2013 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
2014 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
2016 if (fragments.isEmpty())
2019 // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
2020 ClipRect ancestorClipRect = dirtyRect;
2021 if (enclosingPaginationLayer()->parent()) {
2022 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
2023 if (respectOverflowClip == IgnoreOverflowClip)
2024 clipRectsContext.setIgnoreOverflowClip();
2025 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
2026 ancestorClipRect.intersect(dirtyRect);
2029 for (size_t i = 0; i < fragments.size(); ++i) {
2030 LayerFragment& fragment = fragments.at(i);
2032 // Set our four rects with all clipping applied that was internal to the flow thread.
2033 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread);
2035 // Shift to the root-relative physical position used when painting the flow thread in this fragment.
2036 fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2038 // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
2039 // properly clipped by the overflow.
2040 fragment.intersect(ancestorClipRect.rect());
2042 // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
2043 // clip, so the column clip ends up being all we apply.
2044 fragment.intersect(fragment.paginationClip);
2048 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags,
2049 bool shouldPaintContent, const LayoutPoint* offsetFromRoot)
2051 ASSERT(offsetFromRoot);
2052 for (size_t i = 0; i < fragments.size(); ++i) {
2053 LayerFragment& fragment = fragments.at(i);
2054 fragment.shouldPaintContent = shouldPaintContent;
2055 if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) {
2056 LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset;
2057 fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot);
2062 void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2064 LayerFragments enclosingPaginationFragments;
2065 LayoutPoint offsetOfPaginationLayerFromRoot;
2066 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
2067 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
2068 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
2069 shouldRespectOverflowClip(paintFlags, renderer()), &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent);
2071 for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
2072 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
2074 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
2075 // the enclosing pagination layer.
2076 LayoutRect clipRect = fragment.backgroundRect.rect();
2078 // Now compute the clips within a given fragment
2079 if (parent() != enclosingPaginationLayer()) {
2080 enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot);
2082 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize);
2083 if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip)
2084 clipRectsContext.setIgnoreOverflowClip();
2085 LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
2086 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2087 clipRect.intersect(parentClipRect);
2090 parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
2091 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
2092 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
2096 static inline LayoutSize subPixelAccumulationIfNeeded(const LayoutSize& subPixelAccumulation, CompositingState compositingState)
2098 // Only apply the sub-pixel accumulation if we don't paint into our own backing layer, otherwise the position
2099 // of the renderer already includes any sub-pixel offset.
2100 if (compositingState == PaintsIntoOwnBacking)
2101 return LayoutSize();
2102 return subPixelAccumulation;
2105 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
2106 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
2107 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2109 for (size_t i = 0; i < layerFragments.size(); ++i) {
2110 const LayerFragment& fragment = layerFragments.at(i);
2111 if (!fragment.shouldPaintContent)
2114 // Begin transparency layers lazily now that we know we have to paint something.
2115 if (haveTransparency || paintsWithBlendMode())
2116 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
2118 if (localPaintingInfo.clipToDirtyRect) {
2119 // Paint our background first, before painting any child layers.
2120 // Establish the clip used to paint our background.
2121 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
2124 // Paint the background.
2125 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
2126 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2127 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2129 if (localPaintingInfo.clipToDirtyRect)
2130 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2134 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
2135 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
2136 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags paintFlags)
2138 // Begin transparency if we have something to paint.
2139 if (haveTransparency || paintsWithBlendMode()) {
2140 for (size_t i = 0; i < layerFragments.size(); ++i) {
2141 const LayerFragment& fragment = layerFragments.at(i);
2142 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
2143 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
2149 // Optimize clipping for the single fragment case.
2150 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
2152 clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags);
2154 // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
2155 // interleaving of the fragments to work properly.
2156 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments,
2157 context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2159 if (!selectionOnly) {
2160 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2161 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2162 paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
2166 restoreClip(context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
2169 void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context,
2170 const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2172 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1;
2174 for (size_t i = 0; i < layerFragments.size(); ++i) {
2175 const LayerFragment& fragment = layerFragments.at(i);
2176 if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty())
2180 clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags);
2182 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2183 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2186 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2190 void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2191 PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2193 for (size_t i = 0; i < layerFragments.size(); ++i) {
2194 const LayerFragment& fragment = layerFragments.at(i);
2195 if (fragment.outlineRect.isEmpty())
2198 // Paint our own outline
2199 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2200 clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, DoNotIncludeSelfForBorderRadius);
2201 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2202 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
2206 void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2207 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2209 for (size_t i = 0; i < layerFragments.size(); ++i) {
2210 const LayerFragment& fragment = layerFragments.at(i);
2211 if (!fragment.shouldPaintContent)
2214 if (localPaintingInfo.clipToDirtyRect)
2215 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
2218 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
2219 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2220 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2222 if (localPaintingInfo.clipToDirtyRect)
2223 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2227 void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2228 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
2230 for (size_t i = 0; i < layerFragments.size(); ++i) {
2231 const LayerFragment& fragment = layerFragments.at(i);
2232 if (!fragment.shouldPaintContent)
2235 if (localPaintingInfo.clipToDirtyRect)
2236 clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
2238 // Paint the the clipped mask.
2239 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
2240 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2242 if (localPaintingInfo.clipToDirtyRect)
2243 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2247 void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags)
2249 for (size_t i = 0; i < layerFragments.size(); ++i) {
2250 const LayerFragment& fragment = layerFragments.at(i);
2251 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags);
2252 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
2253 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
2254 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2258 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2260 // We need to do multiple passes, breaking up our child layer into strips.
2261 Vector<RenderLayer*> columnLayers;
2262 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
2263 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
2264 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
2265 columnLayers.append(curr);
2266 if (curr->stackingNode() == ancestorNode)
2270 // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before
2271 // updatePaginationRecusive() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
2272 // If this is the case, just bail out, since the upcoming call to updatePaginationRecusive() will repaint the layer.
2273 // FIXME: Is this true anymore? This seems very suspicious.
2274 if (!columnLayers.size())
2277 paintChildLayerIntoColumns(childLayer, context, paintingInfo, paintFlags, columnLayers, columnLayers.size() - 1);
2280 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo,
2281 PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex)
2283 RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer());
2285 ASSERT(columnBlock && columnBlock->hasColumns());
2286 if (!columnBlock || !columnBlock->hasColumns())
2289 LayoutPoint layerOffset;
2290 // FIXME: It looks suspicious to call convertToLayerCoords here
2291 // as canUseConvertToLayerCoords is true for this layer.
2292 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffset);
2294 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
2296 ColumnInfo* colInfo = columnBlock->columnInfo();
2297 unsigned colCount = columnBlock->columnCount(colInfo);
2298 LayoutUnit currLogicalTopOffset = 0;
2299 for (unsigned i = 0; i < colCount; i++) {
2300 // For each rect, we clip to the rect, and then we adjust our coords.
2301 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2302 columnBlock->flipForWritingMode(colRect);
2303 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
2306 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2307 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset);
2309 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
2311 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2312 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset);
2314 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
2317 colRect.moveBy(layerOffset);
2319 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect);
2320 localDirtyRect.intersect(colRect);
2322 if (!localDirtyRect.isEmpty()) {
2323 GraphicsContextStateSaver stateSaver(*context);
2325 // Each strip pushes a clip, since column boxes are specified as being
2326 // like overflow:hidden.
2327 context->clip(enclosingIntRect(colRect));
2330 // Apply a translation transform to change where the layer paints.
2331 TransformationMatrix oldTransform;
2332 bool oldHasTransform = childLayer->transform();
2333 if (oldHasTransform)
2334 oldTransform = *childLayer->transform();
2335 TransformationMatrix newTransform(oldTransform);
2336 newTransform.translateRight(roundToInt(offset.width()), roundToInt(offset.height()));
2338 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
2340 LayerPaintingInfo localPaintingInfo(paintingInfo);
2341 localPaintingInfo.paintDirtyRect = localDirtyRect;
2342 childLayer->paintLayer(context, localPaintingInfo, paintFlags);
2344 if (oldHasTransform)
2345 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
2347 childLayer->m_transform.clear();
2349 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
2350 // This involves subtracting out the position of the layer in our current coordinate space.
2351 LayoutPoint childOffset;
2352 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.rootLayer, childOffset);
2353 TransformationMatrix transform;
2354 transform.translateRight(roundToInt(childOffset.x() + offset.width()), roundToInt(childOffset.y() + offset.height()));
2356 // Apply the transform.
2357 context->concatCTM(transform.toAffineTransform());
2359 // Now do a paint with the root layer shifted to be the next multicol block.
2360 LayerPaintingInfo columnPaintingInfo(paintingInfo);
2361 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1];
2362 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(localDirtyRect);
2363 paintChildLayerIntoColumns(childLayer, context, columnPaintingInfo, paintFlags, columnLayers, colIndex - 1);
2367 // Move to the next position.
2368 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width();
2369 if (columnBlock->style()->isFlippedBlocksWritingMode())
2370 currLogicalTopOffset += blockDelta;
2372 currLogicalTopOffset -= blockDelta;
2376 static inline LayoutRect frameVisibleRect(RenderObject* renderer)
2378 FrameView* frameView = renderer->document().view();
2380 return LayoutRect();
2382 return frameView->visibleContentRect();
2385 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
2387 return hitTest(request, result.hitTestLocation(), result);
2390 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result)
2392 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
2394 // RenderView should make sure to update layout before entering hit testing
2395 ASSERT(!renderer()->frame()->view()->layoutPending());
2396 ASSERT(!renderer()->document().renderView()->needsLayout());
2398 LayoutRect hitTestArea = renderer()->view()->documentRect();
2399 if (!request.ignoreClipping())
2400 hitTestArea.intersect(frameVisibleRect(renderer()));
2402 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hitTestLocation, false);
2404 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
2405 // return ourselves. We do this so mouse events continue getting delivered after a drag has
2406 // exited the WebView, and so hit testing over a scrollbar hits the content document.
2407 if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) {
2408 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point()));
2413 // Now determine if the result is inside an anchor - if the urlElement isn't already set.
2414 Node* node = result.innerNode();
2415 if (node && !result.URLElement())
2416 result.setURLElement(node->enclosingLinkEventParentOrSelf());
2418 // Now return whether we were inside this layer (this will always be true for the root
2423 Node* RenderLayer::enclosingElement() const
2425 for (RenderObject* r = renderer(); r; r = r->parent()) {
2426 if (Node* e = r->node())
2429 ASSERT_NOT_REACHED();
2433 bool RenderLayer::isInTopLayer() const
2435 Node* node = renderer()->node();
2436 return node && node->isElementNode() && toElement(node)->isInTopLayer();
2439 // Compute the z-offset of the point in the transformState.
2440 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
2441 // ray intersects target, and computing the z delta between those two points.
2442 static double computeZOffset(const HitTestingTransformState& transformState)
2444 // We got an affine transform, so no z-offset
2445 if (transformState.m_accumulatedTransform.isAffine())
2448 // Flatten the point into the target plane
2449 FloatPoint targetPoint = transformState.mappedPoint();
2451 // Now map the point back through the transform, which computes Z.
2452 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
2453 return backmappedPoint.z();
2456 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
2457 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
2458 const HitTestingTransformState* containerTransformState,
2459 const LayoutPoint& translationOffset) const
2461 RefPtr<HitTestingTransformState> transformState;
2463 if (containerTransformState) {
2464 // If we're already computing transform state, then it's relative to the container (which we know is non-null).
2465 transformState = HitTestingTransformState::create(*containerTransformState);
2466 convertToLayerCoords(containerLayer, offset);
2468 // If this is the first time we need to make transform state, then base it off of hitTestLocation,
2469 // which is relative to rootLayer.
2470 transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect));
2471 convertToLayerCoords(rootLayer, offset);
2473 offset.moveBy(translationOffset);
2475 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
2476 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
2477 TransformationMatrix containerTransform;
2478 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform);
2479 transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
2481 transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform);
2484 return transformState;
2488 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
2493 // The hit layer is depth-sorting with other layers, so just say that it was hit.
2497 // We need to look at z-depth to decide if this layer was hit.
2499 ASSERT(transformState);
2500 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
2501 double childZOffset = computeZOffset(*transformState);
2502 if (childZOffset > *zOffset) {
2503 *zOffset = childZOffset;
2512 // hitTestLocation and hitTestRect are relative to rootLayer.
2513 // A 'flattening' layer is one preserves3D() == false.
2514 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
2515 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer.
2516 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
2518 // If zOffset is non-null (which indicates that the caller wants z offset information),
2519 // *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
2520 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2521 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform,
2522 const HitTestingTransformState* transformState, double* zOffset)
2524 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
2527 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
2529 // Apply a transform if we have one.
2530 if (transform() && !appliedTransform) {
2531 if (enclosingPaginationLayer())
2532 return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
2534 // Make sure the parent's clip rects have been calculated.
2536 ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize));
2537 // Go ahead and test the enclosing clip now.
2538 if (!clipRect.intersects(hitTestLocation))
2542 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
2545 // Ensure our lists and 3d status are up-to-date.
2546 m_stackingNode->updateLayerListsIfNeeded();
2547 update3DTransformedDescendantStatus();
2549 RefPtr<HitTestingTransformState> localTransformState;
2550 if (appliedTransform) {
2551 // We computed the correct state in the caller (above code), so just reference it.
2552 ASSERT(transformState);
2553 localTransformState = const_cast<HitTestingTransformState*>(transformState);
2554 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
2555 // We need transform state for the first time, or to offset the container state, so create it here.
2556 localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
2559 // Check for hit test on backface if backface-visibility is 'hidden'
2560 if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
2561 TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
2562 // If the z-vector of the matrix is negative, the back is facing towards the viewer.
2563 if (invertedMatrix.m33() < 0)
2567 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
2568 if (localTransformState && !preserves3D()) {
2569 // Keep a copy of the pre-flattening state, for computing z-offsets for the container
2570 unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
2571 // This layer is flattening, so flatten the state passed to descendants.
2572 localTransformState->flatten();
2575 // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
2577 double localZOffset = -std::numeric_limits<double>::infinity();
2578 double* zOffsetForDescendantsPtr = 0;
2579 double* zOffsetForContentsPtr = 0;
2581 bool depthSortDescendants = false;
2582 if (preserves3D()) {
2583 depthSortDescendants = true;
2584 // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
2585 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
2586 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
2587 } else if (zOffset) {
2588 zOffsetForDescendantsPtr = 0;
2589 // Container needs us to give back a z offset for the hit layer.
2590 zOffsetForContentsPtr = zOffset;
2593 // This variable tracks which layer the mouse ends up being inside.
2594 RenderLayer* candidateLayer = 0;
2596 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
2597 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2598 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2600 if (!depthSortDescendants)
2602 candidateLayer = hitLayer;
2605 // Now check our overflow objects.
2606 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2607 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2609 if (!depthSortDescendants)
2611 candidateLayer = hitLayer;
2614 // Collect the fragments. This will compute the clip rectangles for each layer fragment.
2615 LayerFragments layerFragments;
2616 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
2618 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) {
2619 renderer()->updateHitTestResult(result, hitTestLocation.point());
2623 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check
2624 // every fragment in reverse order.
2625 if (isSelfPaintingLayer()) {
2626 // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
2627 HitTestResult tempResult(result.hitTestLocation());
2628 bool insideFragmentForegroundRect = false;
2629 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect)
2630 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
2631 if (result.isRectBasedTest())
2632 result.append(tempResult);
2634 result = tempResult;
2635 if (!depthSortDescendants)
2637 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
2638 candidateLayer = this;
2639 } else if (insideFragmentForegroundRect && result.isRectBasedTest())
2640 result.append(tempResult);
2643 // Now check our negative z-index children.
2644 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2645 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2647 if (!depthSortDescendants)
2649 candidateLayer = hitLayer;
2652 // If we found a layer, return. Child layers, and foreground always render in front of background.
2654 return candidateLayer;
2656 if (isSelfPaintingLayer()) {
2657 HitTestResult tempResult(result.hitTestLocation());
2658 bool insideFragmentBackgroundRect = false;
2659 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect)
2660 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
2661 if (result.isRectBasedTest())
2662 result.append(tempResult);
2664 result = tempResult;
2667 if (insideFragmentBackgroundRect && result.isRectBasedTest())
2668 result.append(tempResult);
2674 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result,
2675 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const
2677 if (layerFragments.isEmpty())
2680 for (int i = layerFragments.size() - 1; i >= 0; --i) {
2681 const LayerFragment& fragment = layerFragments.at(i);
2682 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation))
2683 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation)))
2685 insideClipRect = true;
2686 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter))
2693 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2694 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2696 LayerFragments enclosingPaginationFragments;
2697 LayoutPoint offsetOfPaginationLayerFromRoot;
2698 // FIXME: We're missing a sub-pixel offset here crbug.com/348728
2699 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox, LayoutSize());
2700 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
2701 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
2703 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
2704 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
2706 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
2707 // the enclosing pagination layer.
2708 LayoutRect clipRect = fragment.backgroundRect.rect();
2710 // Now compute the clips within a given fragment
2711 if (parent() != enclosingPaginationLayer()) {
2712 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
2713 LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize)).rect();
2714 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2715 clipRect.intersect(parentClipRect);
2718 if (!hitTestLocation.intersects(clipRect))
2721 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation,
2722 transformState, zOffset, fragment.paginationOffset);
2730 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2731 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
2732 const LayoutPoint& translationOffset)
2734 // Create a transform state to accumulate this transform.
2735 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset);
2737 // If the transform can't be inverted, then don't hit test this layer at all.
2738 if (!newTransformState->m_accumulatedTransform.isInvertible())
2741 // Compute the point and the hit test rect in the coords of this layer by using the values
2742 // from the transformState, which store the point and quad in the coords of the last flattened
2743 // layer, and the accumulated transform which lets up map through preserve-3d layers.
2745 // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z)
2746 // by our container.
2747 FloatPoint localPoint = newTransformState->mappedPoint();
2748 FloatQuad localPointQuad = newTransformState->mappedQuad();
2749 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea();
2750 HitTestLocation newHitTestLocation;
2751 if (hitTestLocation.isRectBasedTest())
2752 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
2754 newHitTestLocation = HitTestLocation(localPoint);
2756 // Now do a hit test with the root layer shifted to be us.
2757 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset);
2760 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const
2762 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
2764 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) {
2765 // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
2766 // a rect-based test.
2767 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
2771 // For positioned generated content, we might still not have a
2772 // node by the time we get to the layer level, since none of
2773 // the content in the layer has an element. So just walk up
2775 if (!result.innerNode() || !result.innerNonSharedNode()) {
2776 Node* e = enclosingElement();
2777 if (!result.innerNode())
2778 result.setInnerNode(e);
2779 if (!result.innerNonSharedNode())
2780 result.setInnerNonSharedNode(e);
2786 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer,
2787 const HitTestRequest& request, HitTestResult& result,
2788 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
2789 const HitTestingTransformState* transformState,
2790 double* zOffsetForDescendants, double* zOffset,
2791 const HitTestingTransformState* unflattenedTransformState,
2792 bool depthSortDescendants)
2794 if (!hasSelfPaintingLayerDescendant())
2797 RenderLayer* resultLayer = 0;
2798 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit);
2799 while (RenderLayerStackingNode* child = iterator.next()) {
2800 RenderLayer* childLayer = child->layer();
2801 RenderLayer* hitLayer = 0;
2802 HitTestResult tempResult(result.hitTestLocation());
2803 if (childLayer->isPaginated())
2804 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
2806 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
2808 // If it a rect-based test, we can safely append the temporary result since it might had hit
2809 // nodes but not necesserily had hitLayer set.
2810 if (result.isRectBasedTest())
2811 result.append(tempResult);
2813 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
2814 resultLayer = hitLayer;
2815 if (!result.isRectBasedTest())
2816 result = tempResult;
2817 if (!depthSortDescendants)
2825 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
2826 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2828 Vector<RenderLayer*> columnLayers;
2829 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
2830 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
2831 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
2832 columnLayers.append(curr);
2833 if (curr->stackingNode() == ancestorNode)
2837 ASSERT(columnLayers.size());
2838 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset,
2839 columnLayers, columnLayers.size() - 1);
2842 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
2843 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
2844 const Vector<RenderLayer*>& columnLayers, size_t columnIndex)
2846 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer());
2848 ASSERT(columnBlock && columnBlock->hasColumns());
2849 if (!columnBlock || !columnBlock->hasColumns())
2852 LayoutPoint layerOffset;
2853 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
2855 ColumnInfo* colInfo = columnBlock->columnInfo();
2856 int colCount = columnBlock->columnCount(colInfo);
2858 // We have to go backwards from the last column to the first.
2859 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
2860 LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent();
2861 LayoutUnit currLogicalTopOffset = 0;
2863 for (i = 0; i < colCount; i++) {
2864 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2865 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
2866 if (columnBlock->style()->isFlippedBlocksWritingMode())
2867 currLogicalTopOffset += blockDelta;
2869 currLogicalTopOffset -= blockDelta;
2871 for (i = colCount - 1; i >= 0; i--) {
2872 // For each rect, we clip to the rect, and then we adjust our coords.
2873 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2874 columnBlock->flipForWritingMode(colRect);
2875 LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
2876 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
2877 if (columnBlock->style()->isFlippedBlocksWritingMode())
2878 currLogicalTopOffset -= blockDelta;
2880 currLogicalTopOffset += blockDelta;
2884 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2885 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset);
2887 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
2889 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2890 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset);
2892 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
2895 colRect.moveBy(layerOffset);
2897 LayoutRect localClipRect(hitTestRect);
2898 localClipRect.intersect(colRect);
2900 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect)) {
2901 RenderLayer* hitLayer = 0;
2903 // Apply a translation transform to change where the layer paints.
2904 TransformationMatrix oldTransform;
2905 bool oldHasTransform = childLayer->transform();
2906 if (oldHasTransform)
2907 oldTransform = *childLayer->transform();
2908 TransformationMatrix newTransform(oldTransform);
2909 newTransform.translateRight(offset.width(), offset.height());
2911 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
2912 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestLocation, false, transformState, zOffset);
2913 if (oldHasTransform)
2914 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
2916 childLayer->m_transform.clear();
2918 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space.
2919 // This involves subtracting out the position of the layer in our current coordinate space.
2920 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
2921 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation, transformState);
2922 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
2923 FloatPoint localPoint = newTransformState->mappedPoint();
2924 FloatQuad localPointQuad = newTransformState->mappedQuad();
2925 LayoutRect localHitTestRect = newTransformState->mappedArea().enclosingBoundingBox();
2926 HitTestLocation newHitTestLocation;
2927 if (hitTestLocation.isRectBasedTest())
2928 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
2930 newHitTestLocation = HitTestLocation(localPoint);
2931 newTransformState->flatten();
2933 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, newHitTestLocation,
2934 newTransformState.get(), zOffset, columnLayers, columnIndex - 1);
2945 void RenderLayer::blockSelectionGapsBoundsChanged()
2947 setNeedsCompositingInputsUpdate();
2950 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
2952 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
2953 blockSelectionGapsBoundsChanged();
2956 void RenderLayer::clearBlockSelectionGapsBounds()
2958 m_blockSelectionGapsBounds = IntRect();
2959 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2960 child->clearBlockSelectionGapsBounds();
2961 blockSelectionGapsBoundsChanged();
2964 void RenderLayer::invalidatePaintForBlockSelectionGaps()
2966 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2967 child->invalidatePaintForBlockSelectionGaps();
2969 if (m_blockSelectionGapsBounds.isEmpty())
2972 LayoutRect rect = m_blockSelectionGapsBounds;
2973 if (renderer()->hasOverflowClip()) {
2974 RenderBox* box = renderBox();
2975 rect.move(-box->scrolledContentOffset());
2976 if (!scrollableArea()->usesCompositedScrolling())
2977 rect.intersect(box->overflowClipRect(LayoutPoint()));
2979 if (renderer()->hasClip())
2980 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint()));
2981 if (!rect.isEmpty())
2982 renderer()->invalidatePaintRectangle(rect);
2985 IntRect RenderLayer::blockSelectionGapsBounds() const
2987 if (!renderer()->isRenderBlock())
2990 RenderBlock* renderBlock = toRenderBlock(renderer());
2991 LayoutRect gapRects = renderBlock->selectionGapRectsForRepaint(renderBlock);
2993 return pixelSnappedIntRect(gapRects);
2996 bool RenderLayer::hasBlockSelectionGapBounds() const
2998 // FIXME: it would be more accurate to return !blockSelectionGapsBounds().isEmpty(), but this is impossible
2999 // at the moment because it causes invalid queries to layout-dependent code (crbug.com/372802).
3000 // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::LayoutClean);
3002 if (!renderer()->isRenderBlock())
3005 return toRenderBlock(renderer())->shouldPaintSelectionGaps();
3008 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
3010 // Always examine the canvas and the root.
3011 // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
3012 // paints the root's background.
3013 if (isRootLayer() || renderer()->isDocumentElement())
3016 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
3017 // can go ahead and return true.
3018 RenderView* view = renderer()->view();
3020 if (view && !renderer()->isRenderInline()) {
3021 if (layerBounds.intersects(damageRect))
3025 // Otherwise we need to compute the bounding box of this single layer and see if it intersects
3027 return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
3030 LayoutRect RenderLayer::logicalBoundingBox() const
3032 // There are three special cases we need to consider.
3033 // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
3034 // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the
3035 // line boxes of all three lines (including overflow on those lines).
3036 // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top
3037 // overflow, we have to create a bounding box that will extend to include this overflow.
3038 // (3) Floats. When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
3039 // as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
3042 if (renderer()->isInline() && renderer()->isRenderInline()) {
3043 result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
3044 } else if (renderer()->isTableRow()) {
3045 // Our bounding box is just the union of all of our cells' border/overflow rects.
3046 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
3047 if (child->isTableCell()) {
3048 LayoutRect bbox = toRenderBox(child)->borderBoxRect();
3050 LayoutRect overflowRect = renderBox()->visualOverflowRect();
3051 if (bbox != overflowRect)
3052 result.unite(overflowRect);
3056 RenderBox* box = renderBox();
3058 result = box->borderBoxRect();
3059 result.unite(box->visualOverflowRect());
3062 ASSERT(renderer()->view());
3066 LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const
3068 LayoutRect result = logicalBoundingBox();
3069 if (m_renderer->isBox())
3070 renderBox()->flipForWritingMode(result);
3072 m_renderer->containingBlock()->flipForWritingMode(result);
3076 delta = *offsetFromRoot;
3078 convertToLayerCoords(ancestorLayer, delta);
3080 result.moveBy(delta);
3084 static void expandRectForReflectionAndStackingChildren(const RenderLayer* ancestorLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result)
3086 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
3087 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer));
3089 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer->stackingNode()->hasPositiveZOrderList());
3092 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(ancestorLayer)->stackingNode());
3095 RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildren);
3096 while (RenderLayerStackingNode* node = iterator.next()) {
3097 // Here we exclude both directly composited layers and squashing layers
3098 // because those RenderLayers don't paint into the graphics layer
3099 // for this RenderLayer. For example, the bounds of squashed RenderLayers
3100 // will be included in the computation of the appropriate squashing
3102 if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()->compositingState() != NotComposited)
3104 result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options));
3108 LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const
3111 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
3113 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
3115 expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggHacks, result);
3117 result.moveBy(offsetFromRoot);
3121 LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLayer, CalculateBoundsOptions options) const
3123 if (!isSelfPaintingLayer())
3124 return LayoutRect();
3127 ancestorLayer = this;
3129 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
3130 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
3131 return LayoutRect();
3133 // The root layer is always just the size of the document.
3135 return m_renderer->view()->unscaledDocumentRect();
3137 const bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform());
3139 LayoutRect localClipRect = clipper().localClipRect();
3140 if (localClipRect != PaintInfo::infiniteRect()) {
3141 if (shouldIncludeTransform)
3142 localClipRect = transform()->mapRect(localClipRect);
3145 convertToLayerCoords(ancestorLayer, delta);
3146 localClipRect.moveBy(delta);
3147 return localClipRect;
3151 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
3153 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
3155 // Reflections are implemented with RenderLayers that hang off of the reflected layer. However,
3156 // the reflection layer subtree does not include the subtree of the parent RenderLayer, so
3157 // a recursive computation of stacking children yields no results. This breaks cases when there are stacking
3158 // children of the parent, that need to be included in reflected composited bounds.
3159 // Fix this by including composited bounds of stacking children of the reflected RenderLayer.
3160 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this)
3161 expandRectForReflectionAndStackingChildren(parent(), options, result);
3163 expandRectForReflectionAndStackingChildren(this, options, result);
3165 // FIXME: We can optimize the size of the composited layers, by not enlarging
3166 // filtered areas with the outsets if we know that the filter is going to render in hardware.
3167 // https://bugs.webkit.org/show_bug.cgi?id=81239
3168 m_renderer->style()->filterOutsets().expandRect(result);
3170 if (shouldIncludeTransform)
3171 result = transform()->mapRect(result);
3174 convertToLayerCoords(ancestorLayer, delta);
3175 result.moveBy(delta);
3179 CompositingState RenderLayer::compositingState() const
3181 ASSERT(isAllowedToQueryCompositingState());
3183 // This is computed procedurally so there is no redundant state variable that
3184 // can get out of sync from the real actual compositing state.
3186 if (m_groupedMapping) {
3187 ASSERT(compositor()->layerSquashingEnabled());
3188 ASSERT(!m_compositedLayerMapping);
3189 return PaintsIntoGroupedBacking;
3192 if (!m_compositedLayerMapping)
3193 return NotComposited;
3195 if (compositedLayerMapping()->paintsIntoCompositedAncestor())
3196 return HasOwnBackingButPaintsIntoAncestor;
3198 return PaintsIntoOwnBacking;
3201 bool RenderLayer::isAllowedToQueryCompositingState() const
3203 if (gCompositingQueryMode == CompositingQueriesAreAllowed)
3205 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
3208 CompositedLayerMapping* RenderLayer::compositedLayerMapping() const
3210 ASSERT(isAllowedToQueryCompositingState());
3211 return m_compositedLayerMapping.get();
3214 GraphicsLayer* RenderLayer::graphicsLayerBacking() const
3216 switch (compositingState()) {
3219 case PaintsIntoGroupedBacking:
3220 return groupedMapping()->squashingLayer();
3222 return compositedLayerMapping()->mainGraphicsLayer();
3226 GraphicsLayer* RenderLayer::graphicsLayerBackingForScrolling() const
3228 switch (compositingState()) {
3231 case PaintsIntoGroupedBacking:
3232 return groupedMapping()->squashingLayer();
3234 return compositedLayerMapping()->scrollingContentsLayer() ? compositedLayerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsLayer();
3238 CompositedLayerMapping* RenderLayer::ensureCompositedLayerMapping()
3240 if (!m_compositedLayerMapping) {
3241 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this));
3242 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3244 updateOrRemoveFilterEffectRenderer();
3246 return m_compositedLayerMapping.get();
3249 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
3251 if (!layerBeingDestroyed) {
3252 // We need to make sure our decendants get a geometry update. In principle,
3253 // we could call setNeedsGraphicsLayerUpdate on our children, but that would
3254 // require walking the z-order lists to find them. Instead, we over-invalidate
3255 // by marking our parent as needing a geometry update.
3256 if (RenderLayer* compositingParent = enclosingLayerWithCompositedLayerMapping(ExcludeSelf))
3257 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3260 m_compositedLayerMapping.clear();
3262 if (!layerBeingDestroyed)
3263 updateOrRemoveFilterEffectRenderer();
3266 void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed)
3268 if (groupedMapping == m_groupedMapping)
3271 if (!layerBeingDestroyed && m_groupedMapping) {
3272 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3273 m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this);
3275 m_groupedMapping = groupedMapping;
3276 if (!layerBeingDestroyed && m_groupedMapping)
3277 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
3280 bool RenderLayer::hasCompositedMask() const
3282 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
3285 bool RenderLayer::hasCompositedClippingMask() const
3287 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer();
3290 bool RenderLayer::clipsCompositingDescendantsWithBorderRadius() const
3292 RenderStyle* style = renderer()->style();
3296 return compositor()->clipsCompositingDescendants(this) && style->hasBorderRadius();
3299 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
3301 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
3304 bool RenderLayer::paintsWithBlendMode() const
3306 return m_renderer->hasBlendMode() && compositingState() != PaintsIntoOwnBacking;
3309 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
3311 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
3314 if (paintsWithTransparency(PaintBehaviorNormal))
3317 // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child
3318 // is visible and that child doesn't cover the entire rect.
3319 if (renderer()->style()->visibility() != VISIBLE)
3322 if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity())
3325 // FIXME: Handle simple transforms.
3326 if (paintsWithTransform(PaintBehaviorNormal))
3329 // FIXME: Remove this check.
3330 // This function should not be called when layer-lists are dirty.
3331 // It is somehow getting triggered during style update.
3332 if (m_stackingNode->zOrderListsDirty() || m_stackingNode->normalFlowListDirty())
3335 // FIXME: We currently only check the immediate renderer,
3336 // which will miss many cases.
3337 if (renderer()->backgroundIsKnownToBeOpaqueInRect(localRect))
3340 // We can't consult child layers if we clip, since they might cover
3341 // parts of the rect that are clipped out.
3342 if (renderer()->hasOverflowClip())
3345 return childBackgroundIsKnownToBeOpaqueInRect(localRect);
3348 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
3350 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren);
3351 while (RenderLayerStackingNode* child = revertseIterator.next()) {
3352 const RenderLayer* childLayer = child->layer();
3353 // Stop at composited paint boundaries.
3354 if (childLayer->isPaintInvalidationContainer())
3357 if (!childLayer->canUseConvertToLayerCoords())
3360 LayoutPoint childOffset;
3361 LayoutRect childLocalRect(localRect);
3362 childLayer->convertToLayerCoords(this, childOffset);
3363 childLocalRect.moveBy(-childOffset);
3365 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect))
3371 bool RenderLayer::shouldBeSelfPaintingLayer() const
3373 if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAcceleratedCompositing())
3375 return m_layerType == NormalLayer
3376 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
3377 || needsCompositedScrolling();
3380 void RenderLayer::updateSelfPaintingLayer()
3382 bool isSelfPaintingLayer = shouldBeSelfPaintingLayer();
3383 if (this->isSelfPaintingLayer() == isSelfPaintingLayer)
3386 m_isSelfPaintingLayer = isSelfPaintingLayer;
3389 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
3392 bool RenderLayer::hasNonEmptyChildRenderers() const
3394 // Some HTML can cause whitespace text nodes to have renderers, like:
3398 // so test for 0x0 RenderTexts here
3399 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
3400 if (!child->hasLayer()) {
3401 if (child->isRenderInline() || !child->isBox())
3404 if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
3411 bool RenderLayer::hasBoxDecorationsOrBackground() const
3413 return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasBackground();
3416 bool RenderLayer::hasVisibleBoxDecorations() const
3418 if (!hasVisibleContent())
3421 return hasBoxDecorationsOrBackground() || hasOverflowControls();
3424 bool RenderLayer::isVisuallyNonEmpty() const
3426 ASSERT(!m_visibleDescendantStatusDirty);
3428 if (hasVisibleContent() && hasNonEmptyChildRenderers())
3431 if (renderer()->isReplaced() || renderer()->hasMask())
3434 if (hasVisibleBoxDecorations())
3440 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
3442 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter()))
3445 updateOrRemoveFilterClients();
3446 updateOrRemoveFilterEffectRenderer();
3449 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const RenderStyle* oldStyle)
3451 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialCompositingReasonsFromStyle;
3452 compositor()->updatePotentialCompositingReasonsFromStyle(this);
3454 // This function implements an optimization for transforms and opacity.
3455 // A common pattern is for a touchmove handler to update the transform
3456 // and/or an opacity of an element every frame while the user moves their
3457 // finger across the screen. The conditions below recognize when the
3458 // compositing state is set up to receive a direct transform or opacity
3461 if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformChanged | StyleDifference::OpacityChanged))
3463 // The potentialCompositingReasonsFromStyle could have changed without
3464 // a corresponding StyleDifference if an animation started or ended.
3465 if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasonsFromStyle)
3467 // We could add support for reflections if we updated the transform on
3468 // the reflection layers.
3469 if (renderer()->hasReflection())
3471 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't
3472 // perform a direct compositing update because the filters code is going
3473 // to produce different output this time around. We can remove this code
3474 // once we fix the chicken/egg bugs in the filters code and delete the
3475 // scheduleSVGFilterLayerUpdateHack().
3476 if (renderer()->node() && renderer()->node()->svgFilterNeedsLayerUpdate())
3478 if (!m_compositedLayerMapping)
3481 // To cut off almost all the work in the compositing update for
3482 // this case, we treat inline transforms has having assumed overlap
3483 // (similar to how we treat animated transforms). Notice that we read
3484 // CompositingReasonInlineTransform from the m_compositingReasons, which
3485 // means that the inline transform actually triggered assumed overlap in
3487 if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInlineTransform))
3490 // We composite transparent RenderLayers differently from non-transparent
3491 // RenderLayers even when the non-transparent RenderLayers are already a
3492 // stacking context.
3493 if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->hasOpacity())
3496 updateTransform(oldStyle, renderer()->style());
3498 // FIXME: Consider introducing a smaller graphics layer update scope
3499 // that just handles transforms and opacity. GraphicsLayerUpdateLocal
3500 // will also program bounds, clips, and many other properties that could
3501 // not possibly have changed.
3502 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
3503 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange);
3507 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
3509 if (attemptDirectCompositingUpdate(diff, oldStyle))
3512 m_stackingNode->updateIsNormalFlowOnly();
3513 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
3515 if (m_scrollableArea)
3516 m_scrollableArea->updateAfterStyleChange(oldStyle);
3518 // Overlay scrollbars can make this layer self-painting so we need
3519 // to recompute the bit once scrollbars have been updated.
3520 updateSelfPaintingLayer();
3522 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
3523 ASSERT(!oldStyle || diff.needsFullLayout());
3524 updateReflectionInfo(oldStyle);
3527 updateDescendantDependentFlags();
3529 updateTransform(oldStyle, renderer()->style());
3530 updateFilters(oldStyle, renderer()->style());
3532 setNeedsCompositingInputsUpdate();
3535 bool RenderLayer::scrollsOverflow() const
3537 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
3538 return scrollableArea->scrollsOverflow();
3543 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
3545 const FilterOperations& filters = style->filter();
3546 if (filters.hasReferenceFilter()) {
3547 for (size_t i = 0; i < filters.size(); ++i) {
3548 FilterOperation* filterOperation = filters.operations().at(i).get();
3549 if (filterOperation->type() != FilterOperation::REFERENCE)
3551 ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
3552 // FIXME: Cache the ReferenceFilter if it didn't change.
3553 RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create();
3554 float zoom = style->effectiveZoom();
3555 referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom));
3556 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
3557 referenceOperation));
3558 referenceOperation->setFilter(referenceFilter.release());
3565 void RenderLayer::updateOrRemoveFilterClients()
3568 removeFilterInfoIfNeeded();
3572 if (renderer()->style()->filter().hasReferenceFilter())
3573 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter());
3574 else if (hasFilterInfo())
3575 filterInfo()->removeReferenceFilterClients();
3578 void RenderLayer::updateOrRemoveFilterEffectRenderer()
3580 // FilterEffectRenderer is only used to render the filters in software mode,
3581 // so we always need to run updateOrRemoveFilterEffectRenderer after the composited
3582 // mode might have changed for this layer.
3583 if (!paintsWithFilters()) {
3584 // Don't delete the whole filter info here, because we might use it
3585 // for loading CSS shader files.
3586 if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
3587 filterInfo->setRenderer(nullptr);
3592 RenderLayerFilterInfo* filterInfo = ensureFilterInfo();
3593 if (!filterInfo->renderer()) {
3594 RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
3595 filterInfo->setRenderer(filterRenderer.release());
3597 // We can optimize away code paths in other places if we know that there are no software filters.
3598 renderer()->document().view()->setHasSoftwareFilters(true);
3601 // If the filter fails to build, remove it from the layer. It will still attempt to
3602 // go through regular processing (e.g. compositing), but never apply anything.
3603 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
3604 filterInfo->setRenderer(nullptr);
3607 void RenderLayer::filterNeedsPaintInvalidation()
3610 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle());
3611 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style recalc, which
3612 // is a problem because this function can be called while performing layout.
3613 // Presumably this represents an illegal data flow of layout or compositing
3614 // information into the style system.
3615 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack();
3618 if (renderer()->view()) {
3619 if (renderer()->frameView()->isInPerformLayout())
3620 renderer()->setShouldDoFullPaintInvalidation(true);
3622 renderer()->paintInvalidationForWholeRenderer();
3626 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const
3628 computeSelfHitTestRects(rects);
3629 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
3630 child->addLayerHitTestRects(rects);
3633 void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const
3635 if (!size().isEmpty()) {
3636 Vector<LayoutRect> rect;
3638 if (renderBox() && renderBox()->scrollsOverflow()) {
3639 // For scrolling layers, rects are taken to be in the space of the contents.
3640 // We need to include the bounding box of the layer in the space of its parent
3641 // (eg. for border / scroll bars) and if it's composited then the entire contents
3642 // as well as they may be on another composited layer. Skip reporting contents
3643 // for non-composited layers as they'll get projected to the same layer as the
3645 if (compositingState() != NotComposited)
3646 rect.append(m_scrollableArea->overflowRect());
3648 rects.set(this, rect);
3649 if (const RenderLayer* parentLayer = parent()) {
3650 LayerHitTestRects::iterator iter = rects.find(parentLayer);
3651 if (iter == rects.end()) {
3652 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(physicalBoundingBox(parentLayer));
3654 iter->value.append(physicalBoundingBox(parentLayer));
3658 rect.append(logicalBoundingBox());
3659 rects.set(this, rect);
3664 void RenderLayer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
3666 renderer()->setShouldDoFullPaintInvalidation(true);
3668 // Disable for reading compositingState() in isPaintInvalidationContainer() below.
3669 DisableCompositingQueryAsserts disabler;
3671 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
3672 if (!child->isPaintInvalidationContainer())
3673 child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
3677 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
3678 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
3680 } // namespace blink
3683 void showLayerTree(const blink::RenderLayer* layer)
3688 if (blink::LocalFrame* frame = layer->renderer()->frame()) {
3689 WTF::String output = externalRepresentation(frame, blink::RenderAsTextShowAllLayers | blink::RenderAsTextShowLayerNesting | blink::RenderAsTextShowCompositedLayers | blink::RenderAsTextShowAddresses | blink::RenderAsTextShowIDAndClass | blink::RenderAsTextDontUpdateLayout | blink::RenderAsTextShowLayoutState);
3690 fprintf(stderr, "%s\n", output.utf8().data());
3694 void showLayerTree(const blink::RenderObject* renderer)
3698 showLayerTree(renderer->enclosingLayer());