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 "CSSPropertyNames.h"
48 #include "HTMLNames.h"
49 #include "RuntimeEnabledFeatures.h"
51 #include "core/animation/ActiveAnimations.h"
52 #include "core/css/PseudoStyleRequest.h"
53 #include "core/dom/Document.h"
54 #include "core/dom/shadow/ShadowRoot.h"
55 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
56 #include "core/frame/Frame.h"
57 #include "core/frame/FrameView.h"
58 #include "core/frame/Settings.h"
59 #include "core/html/HTMLFrameElement.h"
60 #include "core/page/Page.h"
61 #include "core/page/scrolling/ScrollingCoordinator.h"
62 #include "core/rendering/ColumnInfo.h"
63 #include "core/rendering/CompositedLayerMapping.h"
64 #include "core/rendering/FilterEffectRenderer.h"
65 #include "core/rendering/HitTestRequest.h"
66 #include "core/rendering/HitTestResult.h"
67 #include "core/rendering/HitTestingTransformState.h"
68 #include "core/rendering/RenderFlowThread.h"
69 #include "core/rendering/RenderGeometryMap.h"
70 #include "core/rendering/RenderInline.h"
71 #include "core/rendering/RenderLayerCompositor.h"
72 #include "core/rendering/RenderReplica.h"
73 #include "core/rendering/RenderScrollbar.h"
74 #include "core/rendering/RenderScrollbarPart.h"
75 #include "core/rendering/RenderTreeAsText.h"
76 #include "core/rendering/RenderView.h"
77 #include "core/rendering/svg/ReferenceFilterBuilder.h"
78 #include "core/rendering/svg/RenderSVGResourceClipper.h"
79 #include "platform/LengthFunctions.h"
80 #include "platform/Partitions.h"
81 #include "platform/TraceEvent.h"
82 #include "platform/geometry/FloatPoint3D.h"
83 #include "platform/geometry/FloatRect.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"
100 static CompositingQueryMode gCompositingQueryMode =
101 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases;
105 using namespace HTMLNames;
107 RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
109 , m_hasSelfPaintingLayerDescendant(false)
110 , m_hasSelfPaintingLayerDescendantDirty(false)
111 , m_hasOutOfFlowPositionedDescendant(false)
112 , m_hasOutOfFlowPositionedDescendantDirty(true)
113 , m_hasUnclippedDescendant(false)
114 , m_isUnclippedDescendant(false)
115 , m_isRootLayer(renderer->isRenderView())
116 , m_usedTransparency(false)
117 , m_visibleContentStatusDirty(true)
118 , m_hasVisibleContent(false)
119 , m_visibleDescendantStatusDirty(false)
120 , m_hasVisibleDescendant(false)
121 , m_hasVisibleNonLayerContent(false)
122 , m_isPaginated(false)
123 , m_3DTransformedDescendantStatusDirty(true)
124 , m_has3DTransformedDescendant(false)
125 , m_containsDirtyOverlayScrollbars(false)
126 , m_canSkipRepaintRectsUpdateOnScroll(renderer->isTableCell())
127 , m_hasFilterInfo(false)
128 , m_renderer(renderer)
134 , m_staticInlinePosition(0)
135 , m_staticBlockPosition(0)
136 , m_enclosingPaginationLayer(0)
137 , m_3dRenderingContextRoot(0)
138 , m_groupedMapping(0)
139 , m_repainter(renderer)
140 , m_clipper(renderer)
141 , m_blendInfo(renderer)
143 updateStackingNode();
145 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
147 if (!renderer->firstChild() && renderer->style()) {
148 m_visibleContentStatusDirty = false;
149 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
152 updateScrollableArea();
155 RenderLayer::~RenderLayer()
157 if (!m_renderer->documentBeingDestroyed())
158 compositor()->removeOutOfFlowPositionedLayer(this);
160 if (renderer()->frame() && renderer()->frame()->page()) {
161 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
162 scrollingCoordinator->willDestroyRenderLayer(this);
165 removeFilterInfoIfNeeded();
167 if (groupedMapping()) {
168 groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this);
169 setGroupedMapping(0);
172 // Child layers will be deleted by their corresponding render objects, so
173 // we don't need to delete them ourselves.
175 clearCompositedLayerMapping(true);
178 String RenderLayer::debugName() const
180 if (isReflection()) {
181 ASSERT(m_reflectionInfo);
182 return m_reflectionInfo->debugName();
184 return renderer()->debugName();
187 RenderLayerCompositor* RenderLayer::compositor() const
189 if (!renderer()->view())
191 return renderer()->view()->compositor();
194 void RenderLayer::contentChanged(ContentChangeType changeType)
196 DisableCompositingQueryAsserts disabler;
198 // This can get called when video becomes accelerated, so the layers may change.
199 if (changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged)
200 compositor()->updateLayerCompositingState(this);
202 if (m_compositedLayerMapping)
203 m_compositedLayerMapping->contentChanged(changeType);
206 bool RenderLayer::canRender3DTransforms() const
208 return compositor()->canRender3DTransforms();
211 bool RenderLayer::paintsWithFilters() const
213 if (!renderer()->hasFilter())
216 // https://code.google.com/p/chromium/issues/detail?id=343759
217 DisableCompositingQueryAsserts disabler;
218 if (compositingState() != PaintsIntoOwnBacking)
221 if (!m_compositedLayerMapping || !m_compositedLayerMapping->canCompositeFilters())
227 bool RenderLayer::requiresFullLayerImageForFilters() const
229 if (!paintsWithFilters())
231 FilterEffectRenderer* filter = filterRenderer();
232 return filter ? filter->hasFilterThatMovesPixels() : false;
235 LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const
237 hasLayerOffset = true;
240 return LayoutPoint();
242 // This is similar to root() but we check if an ancestor layer would
243 // prevent the optimization from working.
244 const RenderLayer* rootLayer = 0;
245 for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) {
246 hasLayerOffset = parentLayer->canUseConvertToLayerCoords();
248 return LayoutPoint();
250 ASSERT(rootLayer == root());
253 parent()->convertToLayerCoords(rootLayer, offset);
257 void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags)
259 TRACE_EVENT0("blink_rendering", "RenderLayer::updateLayerPositionsAfterLayout");
261 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
262 // https://code.google.com/p/chromium/issues/detail?id=343756
263 DisableCompositingQueryAsserts disabler;
265 RenderGeometryMap geometryMap(UseTransforms);
266 if (this != rootLayer)
267 geometryMap.pushMappingsToAncestor(parent(), 0);
268 updateLayerPositions(&geometryMap, flags);
271 void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags)
273 updateLayerPosition(); // For relpositioned layers or non-positioned layers,
274 // we need to keep in sync, since we may have shifted relative
275 // to our parent layer.
277 geometryMap->pushMappingsToAncestor(this, parent());
279 // Clear our cached clip rect information.
280 m_clipper.clearClipRects();
282 if (hasOverflowControls()) {
283 LayoutPoint offsetFromRoot;
285 offsetFromRoot = LayoutPoint(geometryMap->absolutePoint(FloatPoint()));
287 // FIXME: It looks suspicious to call convertToLayerCoords here
288 // as canUseConvertToLayerCoords may be true for an ancestor layer.
289 convertToLayerCoords(root(), offsetFromRoot);
291 scrollableArea()->positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
294 updateDescendantDependentFlags();
296 if (flags & UpdatePagination)
299 m_isPaginated = false;
300 m_enclosingPaginationLayer = 0;
303 repainter().repaintAfterLayout(geometryMap, flags & CheckForRepaint);
305 // Go ahead and update the reflection's position and size.
306 if (m_reflectionInfo)
307 m_reflectionInfo->reflection()->layout();
309 // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
310 bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
311 if (hasCompositedLayerMapping())
312 flags &= ~IsCompositingUpdateRoot;
314 if (useRegionBasedColumns() && renderer()->isInFlowRenderFlowThread()) {
316 flags |= UpdatePagination;
319 if (renderer()->hasColumns())
320 flags |= UpdatePagination;
322 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
323 child->updateLayerPositions(geometryMap, flags);
325 if ((flags & UpdateCompositingLayers) && hasCompositedLayerMapping()) {
326 CompositedLayerMapping::UpdateAfterLayoutFlags updateFlags = CompositedLayerMapping::CompositingChildrenOnly;
327 if (flags & NeedsFullRepaintInBacking)
328 updateFlags |= CompositedLayerMapping::NeedsFullRepaint;
330 updateFlags |= CompositedLayerMapping::IsUpdateRoot;
331 compositedLayerMapping()->updateAfterLayout(updateFlags);
335 geometryMap->popMappingsToAncestor(parent());
338 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
340 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
341 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
344 layer->m_hasSelfPaintingLayerDescendantDirty = false;
345 layer->m_hasSelfPaintingLayerDescendant = true;
349 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
351 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
352 layer->m_hasSelfPaintingLayerDescendantDirty = true;
353 // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
354 // in this case, there is no need to dirty our ancestors further.
355 if (layer->isSelfPaintingLayer()) {
356 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
362 void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant()
364 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
365 if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFlowPositionedDescendant())
368 layer->setHasOutOfFlowPositionedDescendantDirty(false);
369 layer->setHasOutOfFlowPositionedDescendant(true);
373 void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus()
375 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
376 layer->setHasOutOfFlowPositionedDescendantDirty(true);
378 // We may or may not have an unclipped descendant. If we do, we'll reset
379 // this to true the next time composited scrolling state is updated.
380 layer->setHasUnclippedDescendant(false);
382 // If we have reached an out of flow positioned layer, we know our parent should have an out-of-flow positioned descendant.
383 // In this case, there is no need to dirty our ancestors further.
384 if (layer->renderer()->isOutOfFlowPositioned()) {
385 ASSERT(!parent() || parent()->m_hasOutOfFlowPositionedDescendantDirty || parent()->hasOutOfFlowPositionedDescendant());
391 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
393 const EPosition position = renderer()->style()->position();
394 const EPosition otherPosition = other->renderer()->style()->position();
395 const RenderObject* containingBlock = renderer()->containingBlock();
396 const RenderObject* otherContainingBlock = other->renderer()->containingBlock();
397 const RenderLayer* rootLayer = renderer()->view()->compositor()->rootRenderLayer();
399 // Fixed-position elements are a special case. They are static with respect
400 // to the viewport, which is not represented by any RenderObject, and their
401 // containingBlock() method returns the root HTML element (while its true
402 // containingBlock should really be the viewport). The real measure for a
403 // non-transformed fixed-position element is as follows: any fixed position
404 // element, A, scrolls with respect an element, B, if and only if B is not
407 // Unfortunately, it gets a bit more complicated - a fixed-position element
408 // which has a transform acts exactly as an absolute-position element
409 // (including having a real, non-viewport containing block).
411 // Below, a "root" fixed position element is defined to be one whose
412 // containing block is the root. These root-fixed-position elements are
413 // the only ones that need this special case code - other fixed position
414 // elements, as well as all absolute, relative, and static elements use the
416 const bool isRootFixedPos = position == FixedPosition && containingBlock->enclosingLayer() == rootLayer;
417 const bool otherIsRootFixedPos = otherPosition == FixedPosition && otherContainingBlock->enclosingLayer() == rootLayer;
419 if (isRootFixedPos && otherIsRootFixedPos)
421 if (isRootFixedPos || otherIsRootFixedPos)
424 if (containingBlock == otherContainingBlock)
427 // Maintain a set of containing blocks between the first layer and its
428 // closest scrollable ancestor.
429 HashSet<const RenderObject*> containingBlocks;
430 while (containingBlock) {
431 if (containingBlock->enclosingLayer()->scrollsOverflow())
433 containingBlocks.add(containingBlock);
434 containingBlock = containingBlock->containingBlock();
437 // Do the same for the 2nd layer, but if we find a common containing block,
438 // it means both layers are contained within a single non-scrolling subtree.
439 // Hence, they will not scroll with respect to each other.
440 while (otherContainingBlock) {
441 if (containingBlocks.contains(otherContainingBlock))
443 if (otherContainingBlock->enclosingLayer()->scrollsOverflow())
445 otherContainingBlock = otherContainingBlock->containingBlock();
451 void RenderLayer::updateLayerPositionsAfterDocumentScroll()
453 ASSERT(this == renderer()->view()->layer());
455 RenderGeometryMap geometryMap(UseTransforms);
456 updateLayerPositionsAfterScroll(&geometryMap);
459 void RenderLayer::updateLayerPositionsAfterOverflowScroll()
461 RenderGeometryMap geometryMap(UseTransforms);
462 RenderView* view = renderer()->view();
463 if (this != view->layer())
464 geometryMap.pushMappingsToAncestor(parent(), 0);
466 // FIXME: why is it OK to not check the ancestors of this layer in order to
467 // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
468 updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
471 void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags)
473 // FIXME: This shouldn't be needed, but there are some corner cases where
474 // these flags are still dirty. Update so that the check below is valid.
475 updateDescendantDependentFlags();
477 // If we have no visible content and no visible descendants, there is no point recomputing
478 // our rectangles as they will be empty. If our visibility changes, we are expected to
479 // recompute all our positions anyway.
480 if (subtreeIsInvisible())
483 bool positionChanged = updateLayerPosition();
485 flags |= HasChangedAncestor;
488 geometryMap->pushMappingsToAncestor(this, parent());
490 if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
491 m_clipper.clearClipRects();
493 if (renderer()->style()->hasViewportConstrainedPosition())
494 flags |= HasSeenViewportConstrainedAncestor;
496 if (renderer()->hasOverflowClip())
497 flags |= HasSeenAncestorWithOverflowClip;
499 if (flags & HasSeenViewportConstrainedAncestor
500 || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip && !m_canSkipRepaintRectsUpdateOnScroll)) {
501 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
502 // https://code.google.com/p/chromium/issues/detail?id=343756
503 DisableCompositingQueryAsserts disabler;
504 // FIXME: We could track the repaint container as we walk down the tree.
505 repainter().computeRepaintRects(renderer()->containerForRepaint(), geometryMap);
507 // Check that RenderLayerRepainter's cached rects are correct.
508 // FIXME: re-enable these assertions when the issue with table cells is resolved: https://bugs.webkit.org/show_bug.cgi?id=103432
509 // ASSERT(repainter().m_repaintRect == renderer()->clippedOverflowRectForRepaint(renderer()->containerForRepaint()));
510 // ASSERT(repainter().m_outlineBox == renderer()->outlineBoundsForRepaint(renderer()->containerForRepaint(), geometryMap));
513 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
514 child->updateLayerPositionsAfterScroll(geometryMap, flags);
516 // We don't update our reflection as scrolling is a translation which does not change the size()
517 // of an object, thus RenderReplica will still repaint itself properly as the layer position was
521 geometryMap->popMappingsToAncestor(parent());
524 void RenderLayer::updateTransform()
526 // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
527 // so check style too.
528 bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform();
529 bool had3DTransform = has3DTransform();
531 bool hadTransform = m_transform;
532 if (hasTransform != hadTransform) {
534 m_transform = adoptPtr(new TransformationMatrix);
538 // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
539 m_clipper.clearClipRectsIncludingDescendants();
543 RenderBox* box = renderBox();
545 m_transform->makeIdentity();
546 box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
547 makeMatrixRenderable(*m_transform, canRender3DTransforms());
550 if (had3DTransform != has3DTransform())
551 dirty3DTransformedDescendantStatus();
554 // Note: this function assumes that all ancestors have an updated 3d rendering context root.
555 void RenderLayer::update3dRenderingContext()
557 m_3dRenderingContextRoot = 0;
559 if (!shouldFlattenTransform())
560 m_3dRenderingContextRoot = this;
562 if (RenderObject* containingBlock = renderer()->containingBlock()) {
563 if (RenderLayer* ancestorLayer = containingBlock->enclosingLayer()) {
564 if (!ancestorLayer->shouldFlattenTransform())
565 m_3dRenderingContextRoot = ancestorLayer->renderingContextRoot();
570 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
573 return TransformationMatrix();
575 // m_transform includes transform-origin, so we need to recompute the transform here.
576 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
577 RenderBox* box = renderBox();
578 TransformationMatrix currTransform;
579 box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
580 makeMatrixRenderable(currTransform, canRender3DTransforms());
581 return currTransform;
587 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
590 return TransformationMatrix();
592 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
593 TransformationMatrix matrix = *m_transform;
594 makeMatrixRenderable(matrix, false /* flatten 3d */);
601 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
603 const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
605 if (layer->renderer()->hasOverflowClip())
606 return const_cast<RenderLayer*>(layer);
608 layer = layer->parent();
613 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
615 RenderView* view = renderer->view();
616 RenderLayerModelObject* prevBlock = renderer;
617 RenderBlock* containingBlock;
618 for (containingBlock = renderer->containingBlock();
619 containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
620 containingBlock = containingBlock->containingBlock())
621 prevBlock = containingBlock;
623 // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
624 if (containingBlock != ancestorColumnsRenderer)
627 // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
628 if (prevBlock->isOutOfFlowPositioned())
631 // Otherwise we are paginated by the columns block.
635 bool RenderLayer::useRegionBasedColumns() const
637 return renderer()->document().regionBasedColumnsEnabled();
640 void RenderLayer::updatePagination()
642 m_isPaginated = false;
643 m_enclosingPaginationLayer = 0;
645 if (hasCompositedLayerMapping() || !parent())
646 return; // FIXME: We will have to deal with paginated compositing layers someday.
647 // FIXME: For now the RenderView can't be paginated. Eventually printing will move to a model where it is though.
649 // The main difference between the paginated booleans for the old column code and the new column code
650 // is that each paginated layer has to paint on its own with the new code. There is no
651 // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on
652 // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and
653 // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
654 // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
655 // to that layer easily.
656 bool regionBasedColumnsUsed = useRegionBasedColumns();
657 if (regionBasedColumnsUsed && renderer()->isInFlowRenderFlowThread()) {
658 m_enclosingPaginationLayer = this;
662 if (m_stackingNode->isNormalFlowOnly()) {
663 if (regionBasedColumnsUsed) {
664 // Content inside a transform is not considered to be paginated, since we simply
665 // paint the transform multiple times in each column, so we don't have to use
666 // fragments for the transformed content.
667 m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
668 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
669 m_enclosingPaginationLayer = 0;
671 m_isPaginated = parent()->renderer()->hasColumns();
675 // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
676 // we find one, then we just check its pagination status.
677 if (regionBasedColumnsUsed) {
678 RenderView* view = renderer()->view();
679 RenderBlock* containingBlock;
680 for (containingBlock = renderer()->containingBlock();
681 containingBlock && containingBlock != view;
682 containingBlock = containingBlock->containingBlock()) {
683 if (containingBlock->hasLayer()) {
684 // Content inside a transform is not considered to be paginated, since we simply
685 // paint the transform multiple times in each column, so we don't have to use
686 // fragments for the transformed content.
687 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer();
688 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
689 m_enclosingPaginationLayer = 0;
696 // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
697 RenderLayerStackingNode* ancestorStackingContainerNode = m_stackingNode->ancestorStackingContainerNode();
698 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
699 if (curr->renderer()->hasColumns()) {
700 m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
703 if (curr->stackingNode() == ancestorStackingContainerNode)
708 void RenderLayer::setHasVisibleContent()
710 if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
711 ASSERT(!parent() || parent()->hasVisibleDescendant());
715 m_visibleContentStatusDirty = false;
716 m_hasVisibleContent = true;
717 repainter().computeRepaintRects(renderer()->containerForRepaint());
718 if (!m_stackingNode->isNormalFlowOnly()) {
719 // We don't collect invisible layers in z-order lists if we are not in compositing mode.
720 // As we became visible, we need to dirty our stacking containers ancestors to be properly
721 // collected. FIXME: When compositing, we could skip this dirtying phase.
722 for (RenderLayerStackingNode* sc = m_stackingNode->ancestorStackingContainerNode(); sc; sc = sc->ancestorStackingContainerNode()) {
723 sc->dirtyZOrderLists();
724 if (sc->layer()->hasVisibleContent())
730 parent()->setAncestorChainHasVisibleDescendant();
733 void RenderLayer::dirtyVisibleContentStatus()
735 m_visibleContentStatusDirty = true;
737 parent()->dirtyAncestorChainVisibleDescendantStatus();
740 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
742 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
743 if (layer->m_visibleDescendantStatusDirty)
746 layer->m_visibleDescendantStatusDirty = true;
750 void RenderLayer::setAncestorChainHasVisibleDescendant()
752 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
753 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
756 layer->m_hasVisibleDescendant = true;
757 layer->m_visibleDescendantStatusDirty = false;
761 void RenderLayer::updateHasUnclippedDescendant()
763 TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasUnclippedDescendant");
764 ASSERT(renderer()->isOutOfFlowPositioned());
765 if (!m_hasVisibleContent && !m_hasVisibleDescendant)
768 FrameView* frameView = renderer()->view()->frameView();
772 const RenderObject* containingBlock = renderer()->containingBlock();
773 setIsUnclippedDescendant(false);
774 for (RenderLayer* ancestor = parent(); ancestor && ancestor->renderer() != containingBlock; ancestor = ancestor->parent()) {
775 // TODO(vollick): This isn't quite right. Whenever ancestor is composited and clips
776 // overflow, we're technically unclipped. However, this will currently cause a huge
777 // number of layers to report that they are unclipped. Eventually, when we've formally
778 // separated the clipping, transform, opacity, and stacking trees here and in the
779 // compositor, we will be able to relax this restriction without it being prohibitively
780 // expensive (currently, we have to do a lot of work in the compositor to honor a
781 // clip child/parent relationship).
782 if (ancestor->scrollsOverflow())
783 setIsUnclippedDescendant(true);
784 ancestor->setHasUnclippedDescendant(true);
788 // FIXME: this is quite brute-force. We could be more efficient if we were to
789 // track state and update it as appropriate as changes are made in the RenderObject tree.
790 void RenderLayer::updateHasVisibleNonLayerContent()
792 TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasVisibleNonLayerContent");
793 m_hasVisibleNonLayerContent = false;
794 for (RenderObject* r = renderer()->firstChild(); r; r = r->nextSibling()) {
795 if (!r->hasLayer()) {
796 m_hasVisibleNonLayerContent = true;
802 static bool subtreeContainsOutOfFlowPositionedLayer(const RenderLayer* subtreeRoot)
804 return (subtreeRoot->renderer() && subtreeRoot->renderer()->isOutOfFlowPositioned()) || subtreeRoot->hasOutOfFlowPositionedDescendant();
807 void RenderLayer::updateDescendantDependentFlags()
809 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) {
810 m_hasVisibleDescendant = false;
811 m_hasSelfPaintingLayerDescendant = false;
812 m_hasOutOfFlowPositionedDescendant = false;
814 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
815 child->updateDescendantDependentFlags();
817 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
818 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
819 bool hasOutOfFlowPositionedDescendant = subtreeContainsOutOfFlowPositionedLayer(child);
821 m_hasVisibleDescendant |= hasVisibleDescendant;
822 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
823 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
825 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && hasOutOfFlowPositionedDescendant)
829 m_visibleDescendantStatusDirty = false;
830 m_hasSelfPaintingLayerDescendantDirty = false;
831 m_hasOutOfFlowPositionedDescendantDirty = false;
834 if (m_blendInfo.childLayerHasBlendModeStatusDirty()) {
835 m_blendInfo.setChildLayerHasBlendMode(false);
836 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
837 if (!child->stackingNode()->isStackingContext())
838 child->updateDescendantDependentFlags();
840 bool childLayerHasBlendMode = child->blendInfo().childLayerHasBlendModeWhileDirty();
841 childLayerHasBlendMode |= child->paintsWithBlendMode()
842 || (childLayerHasBlendMode && !child->stackingNode()->isStackingContext());
844 m_blendInfo.setChildLayerHasBlendMode(childLayerHasBlendMode);
846 if (childLayerHasBlendMode)
849 m_blendInfo.setChildLayerHasBlendModeStatusDirty(false);
852 if (m_visibleContentStatusDirty) {
853 if (renderer()->style()->visibility() == VISIBLE)
854 m_hasVisibleContent = true;
856 // layer may be hidden but still have some visible content, check for this
857 m_hasVisibleContent = false;
858 RenderObject* r = renderer()->firstChild();
860 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
861 m_hasVisibleContent = true;
864 if (r->firstChild() && !r->hasLayer())
866 else if (r->nextSibling())
867 r = r->nextSibling();
873 } while (r && !r->nextSibling());
875 r = r->nextSibling();
879 m_visibleContentStatusDirty = false;
883 void RenderLayer::dirty3DTransformedDescendantStatus()
885 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContainerNode();
889 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
891 // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
892 // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
893 while (stackingNode && stackingNode->layer()->preserves3D()) {
894 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
895 stackingNode = stackingNode->ancestorStackingContainerNode();
899 // Return true if this layer or any preserve-3d descendants have 3d.
900 bool RenderLayer::update3DTransformedDescendantStatus()
902 if (m_3DTransformedDescendantStatusDirty) {
903 m_has3DTransformedDescendant = false;
905 m_stackingNode->updateZOrderLists();
907 // Transformed or preserve-3d descendants can only be in the z-order lists, not
908 // in the normal flow list, so we only need to check those.
909 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren);
910 while (RenderLayerStackingNode* node = iterator.next())
911 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDescendantStatus();
913 m_3DTransformedDescendantStatusDirty = false;
916 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
917 // the m_has3DTransformedDescendant set.
919 return has3DTransform() || m_has3DTransformedDescendant;
921 return has3DTransform();
924 bool RenderLayer::updateLayerPosition()
926 LayoutPoint localPoint;
927 LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
928 if (renderer()->isInline() && renderer()->isRenderInline()) {
929 RenderInline* inlineFlow = toRenderInline(renderer());
930 IntRect lineBox = inlineFlow->linesBoundingBox();
931 setSize(lineBox.size());
932 inlineBoundingBoxOffset = toSize(lineBox.location());
933 localPoint += inlineBoundingBoxOffset;
934 } else if (RenderBox* box = renderBox()) {
935 // FIXME: Is snapping the size really needed here for the RenderBox case?
936 setSize(pixelSnappedIntSize(box->size(), box->location()));
937 localPoint += box->topLeftLocationOffset();
940 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) {
941 // We must adjust our position by walking up the render tree looking for the
942 // nearest enclosing object with a layer.
943 RenderObject* curr = renderer()->parent();
944 while (curr && !curr->hasLayer()) {
945 if (curr->isBox() && !curr->isTableRow()) {
946 // Rows and cells share the same coordinate space (that of the section).
947 // Omit them when computing our xpos/ypos.
948 localPoint += toRenderBox(curr)->topLeftLocationOffset();
950 curr = curr->parent();
952 if (curr->isBox() && curr->isTableRow()) {
953 // Put ourselves into the row coordinate space.
954 localPoint -= toRenderBox(curr)->topLeftLocationOffset();
958 // Subtract our parent's scroll offset.
959 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
960 RenderLayer* positionedParent = enclosingPositionedAncestor();
962 // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
963 if (positionedParent->renderer()->hasOverflowClip()) {
964 LayoutSize offset = positionedParent->renderBox()->scrolledContentOffset();
965 localPoint -= offset;
968 if (renderer()->isOutOfFlowPositioned() && positionedParent->renderer()->isInFlowPositioned() && positionedParent->renderer()->isRenderInline()) {
969 LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(toRenderBox(renderer()));
970 localPoint += offset;
972 } else if (parent()) {
973 if (hasCompositedLayerMapping()) {
974 // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
975 // They won't split across columns properly.
976 LayoutSize columnOffset;
977 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isRoot() && renderer()->view()->hasColumns())
978 renderer()->view()->adjustForColumns(columnOffset, localPoint);
980 parent()->renderer()->adjustForColumns(columnOffset, localPoint);
982 localPoint += columnOffset;
985 if (parent()->renderer()->hasOverflowClip()) {
986 IntSize scrollOffset = parent()->renderBox()->scrolledContentOffset();
987 localPoint -= scrollOffset;
991 bool positionOrOffsetChanged = false;
992 if (renderer()->isInFlowPositioned()) {
993 LayoutSize newOffset = toRenderBoxModelObject(renderer())->offsetForInFlowPosition();
994 positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition;
995 m_offsetForInFlowPosition = newOffset;
996 localPoint.move(m_offsetForInFlowPosition);
998 m_offsetForInFlowPosition = LayoutSize();
1001 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
1002 localPoint -= inlineBoundingBoxOffset;
1004 positionOrOffsetChanged |= location() != localPoint;
1005 setLocation(localPoint);
1006 return positionOrOffsetChanged;
1009 TransformationMatrix RenderLayer::perspectiveTransform() const
1011 if (!renderer()->hasTransform())
1012 return TransformationMatrix();
1014 RenderStyle* style = renderer()->style();
1015 if (!style->hasPerspective())
1016 return TransformationMatrix();
1018 // Maybe fetch the perspective from the backing?
1019 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
1020 const float boxWidth = borderBox.width();
1021 const float boxHeight = borderBox.height();
1023 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth);
1024 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight);
1026 // A perspective origin of 0,0 makes the vanishing point in the center of the element.
1027 // We want it to be in the top-left, so subtract half the height and width.
1028 perspectiveOriginX -= boxWidth / 2.0f;
1029 perspectiveOriginY -= boxHeight / 2.0f;
1031 TransformationMatrix t;
1032 t.translate(perspectiveOriginX, perspectiveOriginY);
1033 t.applyPerspective(style->perspective());
1034 t.translate(-perspectiveOriginX, -perspectiveOriginY);
1039 FloatPoint RenderLayer::perspectiveOrigin() const
1041 if (!renderer()->hasTransform())
1042 return FloatPoint();
1044 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
1045 RenderStyle* style = renderer()->style();
1047 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width()),
1048 floatValueForLength(style->perspectiveOriginY(), borderBox.height()));
1051 static inline bool isFixedPositionedContainer(RenderLayer* layer)
1053 return layer->isRootLayer() || layer->hasTransform();
1056 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
1058 RenderLayer* curr = parent();
1059 while (curr && !curr->isPositionedContainer())
1060 curr = curr->parent();
1065 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
1067 RenderLayer* curr = parent();
1068 while (curr && !curr->isRootLayer() && !curr->transform())
1069 curr = curr->parent();
1074 const RenderLayer* RenderLayer::compositingContainer() const
1076 return stackingNode()->isNormalFlowOnly() ? parent() : (stackingNode()->ancestorStackingContainerNode() ? stackingNode()->ancestorStackingContainerNode()->layer() : 0);
1079 // FIXME: having two different functions named enclosingCompositingLayer and enclosingCompositingLayerForRepaint
1080 // is error-prone and misleading for reading code that uses these functions - especially compounded with
1081 // the includeSelf option. It is very likely that we don't even want either of these functions; A layer
1082 // should be told explicitly which GraphicsLayer is the repaintContainer for a RenderLayer, and
1083 // any other use cases should probably have an API between the non-compositing and compositing sides of code.
1084 RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
1086 ASSERT(isAllowedToQueryCompositingState());
1088 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
1089 return const_cast<RenderLayer*>(this);
1091 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
1092 if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking)
1093 return const_cast<RenderLayer*>(curr);
1099 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
1101 ASSERT(isAllowedToQueryCompositingState());
1103 if ((includeSelf == IncludeSelf) && (compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking))
1104 return const_cast<RenderLayer*>(this);
1106 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
1107 if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == PaintsIntoGroupedBacking)
1108 return const_cast<RenderLayer*>(curr);
1114 RenderLayer* RenderLayer::ancestorCompositedScrollingLayer() const
1116 ASSERT(isAllowedToQueryCompositingState());
1118 if (!renderer()->acceleratedCompositingForOverflowScrollEnabled())
1121 RenderObject* containingBlock = renderer()->containingBlock();
1122 if (!containingBlock)
1125 for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
1126 if (ancestorLayer->needsCompositedScrolling())
1127 return ancestorLayer;
1133 RenderLayer* RenderLayer::ancestorScrollingLayer() const
1135 RenderObject* containingBlock = renderer()->containingBlock();
1136 if (!containingBlock)
1139 for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
1140 if (ancestorLayer->scrollsOverflow())
1141 return ancestorLayer;
1147 RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
1149 const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
1150 for (; curr; curr = curr->parent()) {
1151 if (curr->requiresFullLayerImageForFilters())
1152 return const_cast<RenderLayer*>(curr);
1158 bool RenderLayer::hasAncestorWithFilterOutsets() const
1160 for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1161 RenderLayerModelObject* renderer = curr->renderer();
1162 if (renderer->style()->hasFilterOutsets())
1168 bool RenderLayer::cannotBlitToWindow() const
1170 if (isTransparent() || m_reflectionInfo || hasTransform())
1174 return parent()->cannotBlitToWindow();
1177 bool RenderLayer::isTransparent() const
1179 if (renderer()->node() && renderer()->node()->isSVGElement())
1182 return renderer()->isTransparent() || renderer()->hasMask();
1185 RenderLayer* RenderLayer::transparentPaintingAncestor()
1187 if (hasCompositedLayerMapping())
1190 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1191 if (curr->hasCompositedLayerMapping())
1193 if (curr->isTransparent())
1199 enum TransparencyClipBoxBehavior {
1200 PaintingTransparencyClipBox,
1201 HitTestingTransparencyClipBox
1204 enum TransparencyClipBoxMode {
1205 DescendantsOfTransparencyClipBox,
1206 RootOfTransparencyClipBox
1209 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
1211 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1212 TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1214 // If we have a mask, then the clip is limited to the border box area (and there is
1215 // no need to examine child layers).
1216 if (!layer->renderer()->hasMask()) {
1217 // Note: we don't have to walk z-order lists since transparent elements always establish
1218 // a stacking container. This means we can just walk the layer tree directly.
1219 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1220 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
1221 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
1225 // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire
1226 // current transparencyClipBox to catch all child layers.
1227 // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1228 // size into the parent layer.
1229 if (layer->renderer()->hasReflection()) {
1231 layer->convertToLayerCoords(rootLayer, delta);
1232 clipRect.move(-delta.x(), -delta.y());
1233 clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1234 clipRect.moveBy(delta);
1238 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1239 TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
1241 // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1242 // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
1243 // would be better to respect clips.
1245 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
1246 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) {
1247 // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1248 // the transformed layer and all of its children.
1249 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
1250 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1252 layer->convertToLayerCoords(rootLayerForTransform, delta);
1254 TransformationMatrix transform;
1255 transform.translate(delta.x(), delta.y());
1256 transform = transform * *layer->transform();
1258 // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1259 // paints unfragmented.
1260 LayoutRect clipRect = layer->boundingBox(layer);
1261 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
1262 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1263 LayoutRect result = transform.mapRect(clipRect);
1264 if (!paginationLayer)
1267 // We have to break up the transformed extent across our columns.
1268 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1269 // get our true bounding box.
1270 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1271 result = enclosingFlowThread->fragmentsBoundingBox(result);
1273 LayoutPoint rootLayerDelta;
1274 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1275 result.moveBy(rootLayerDelta);
1279 LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
1280 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1281 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1285 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1287 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1290 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1292 bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
1293 if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency))
1296 RenderLayer* ancestor = transparentPaintingAncestor();
1298 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
1300 if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) {
1301 m_usedTransparency = true;
1303 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
1304 context->clip(clipRect);
1306 if (paintsWithBlendMode())
1307 context->setCompositeOperation(context->compositeOperation(), m_blendInfo.blendMode());
1309 context->beginTransparencyLayer(renderer()->opacity());
1311 if (paintsWithBlendMode())
1312 context->setCompositeOperation(context->compositeOperation(), blink::WebBlendModeNormal);
1313 #ifdef REVEAL_TRANSPARENCY_LAYERS
1314 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
1315 context->fillRect(clipRect);
1320 void* RenderLayer::operator new(size_t sz)
1322 return partitionAlloc(Partitions::getRenderingPartition(), sz);
1325 void RenderLayer::operator delete(void* ptr)
1330 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1332 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1334 child->setPreviousSibling(prevSibling);
1335 prevSibling->setNextSibling(child);
1336 ASSERT(prevSibling != child);
1338 setFirstChild(child);
1341 beforeChild->setPreviousSibling(child);
1342 child->setNextSibling(beforeChild);
1343 ASSERT(beforeChild != child);
1345 setLastChild(child);
1347 child->setParent(this);
1349 if (child->stackingNode()->isNormalFlowOnly())
1350 m_stackingNode->dirtyNormalFlowList();
1352 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) {
1353 // Dirty the z-order list in which we are contained. The ancestorStackingContainerNode() can be null in the
1354 // case where we're building up generated content layers. This is ok, since the lists will start
1355 // off dirty in that case anyway.
1356 child->stackingNode()->dirtyStackingContainerZOrderLists();
1359 child->updateDescendantDependentFlags();
1360 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1361 setAncestorChainHasVisibleDescendant();
1363 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1364 setAncestorChainHasSelfPaintingLayerDescendant();
1366 if (child->paintsWithBlendMode() || child->blendInfo().childLayerHasBlendMode())
1367 m_blendInfo.setAncestorChainBlendedDescendant();
1369 if (subtreeContainsOutOfFlowPositionedLayer(child)) {
1370 // Now that the out of flow positioned descendant is in the tree, we
1371 // need to tell the compositor to reevaluate the compositing
1372 // requirements since we may be able to mark more layers as having
1373 // an 'unclipped' descendant.
1374 compositor()->setNeedsUpdateCompositingRequirementsState();
1375 setAncestorChainHasOutOfFlowPositionedDescendant();
1378 // When we first dirty a layer, we will also dirty all the siblings in that
1379 // layer's stacking context. We need to manually do it here as well, in case
1380 // we're adding this layer after the stacking context has already been
1382 child->stackingNode()->setDescendantsAreContiguousInStackingOrderDirty(true);
1383 compositor()->layerWasAdded(this, child);
1386 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1388 if (!renderer()->documentBeingDestroyed())
1389 compositor()->layerWillBeRemoved(this, oldChild);
1392 if (oldChild->previousSibling())
1393 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1394 if (oldChild->nextSibling())
1395 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1397 if (m_first == oldChild)
1398 m_first = oldChild->nextSibling();
1399 if (m_last == oldChild)
1400 m_last = oldChild->previousSibling();
1402 if (oldChild->stackingNode()->isNormalFlowOnly())
1403 m_stackingNode->dirtyNormalFlowList();
1404 if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) {
1405 // Dirty the z-order list in which we are contained. When called via the
1406 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1407 // from the main layer tree, so we need to null-check the |stackingContainer| value.
1408 oldChild->stackingNode()->dirtyStackingContainerZOrderLists();
1411 oldChild->setPreviousSibling(0);
1412 oldChild->setNextSibling(0);
1413 oldChild->setParent(0);
1415 oldChild->updateDescendantDependentFlags();
1416 if (subtreeContainsOutOfFlowPositionedLayer(oldChild)) {
1417 // It may now be the case that a layer no longer has an unclipped
1418 // descendant. Let the compositor know that it needs to reevaluate
1419 // its compositing requirements to check this.
1420 compositor()->setNeedsUpdateCompositingRequirementsState();
1421 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1424 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1425 dirtyAncestorChainVisibleDescendantStatus();
1427 if (oldChild->paintsWithBlendMode() || oldChild->blendInfo().childLayerHasBlendMode())
1428 m_blendInfo.dirtyAncestorChainBlendedDescendantStatus();
1430 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
1431 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1436 void RenderLayer::removeOnlyThisLayer()
1441 compositor()->layerWillBeRemoved(m_parent, this);
1443 // Dirty the clip rects.
1444 m_clipper.clearClipRectsIncludingDescendants();
1446 RenderLayer* nextSib = nextSibling();
1448 // Remove the child reflection layer before moving other child layers.
1449 // The reflection layer should not be moved to the parent.
1450 if (m_reflectionInfo)
1451 removeChild(m_reflectionInfo->reflectionLayer());
1453 // Now walk our kids and reattach them to our parent.
1454 RenderLayer* current = m_first;
1456 RenderLayer* next = current->nextSibling();
1457 removeChild(current);
1458 m_parent->addChild(current, nextSib);
1459 current->repainter().setRepaintStatus(NeedsFullRepaint);
1460 current->updateLayerPositions(0); // FIXME: use geometry map.
1464 // Remove us from the parent.
1465 m_parent->removeChild(this);
1466 m_renderer->destroyLayer();
1469 void RenderLayer::insertOnlyThisLayer()
1471 if (!m_parent && renderer()->parent()) {
1472 // We need to connect ourselves when our renderer() has a parent.
1473 // Find our enclosingLayer and add ourselves.
1474 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
1475 ASSERT(parentLayer);
1476 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
1477 parentLayer->addChild(this, beforeChild);
1480 // Remove all descendant layers from the hierarchy and add them to the new position.
1481 for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
1482 curr->moveLayers(m_parent, this);
1484 // Clear out all the clip rects.
1485 m_clipper.clearClipRectsIncludingDescendants();
1488 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation) const
1490 LayoutPoint location = roundedLocation;
1491 convertToLayerCoords(ancestorLayer, location);
1492 roundedLocation = roundedIntPoint(location);
1495 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect) const
1497 LayoutRect rect = roundedRect;
1498 convertToLayerCoords(ancestorLayer, rect);
1499 roundedRect = pixelSnappedIntRect(rect);
1502 // Returns the layer reached on the walk up towards the ancestor.
1503 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
1505 ASSERT(ancestorLayer != layer);
1507 const RenderLayerModelObject* renderer = layer->renderer();
1508 EPosition position = renderer->style()->position();
1510 // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great.
1511 RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer->flowThreadContainingBlock() : 0;
1512 if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
1513 fixedFlowThreadContainer = 0;
1515 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1516 // may need to be revisited in a future patch.
1517 // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1518 // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be
1519 // positioned in a completely different place in the viewport (RenderView).
1520 if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
1521 // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1522 // localToAbsolute() on the RenderView.
1523 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed);
1524 location += LayoutSize(absPos.x(), absPos.y());
1525 return ancestorLayer;
1528 // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1529 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1530 // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1531 if (position == FixedPosition && !fixedFlowThreadContainer) {
1532 // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1533 // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1534 // so we should always find the ancestor at or before we find the fixed position container.
1535 RenderLayer* fixedPositionContainerLayer = 0;
1536 bool foundAncestor = false;
1537 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1538 if (currLayer == ancestorLayer)
1539 foundAncestor = true;
1541 if (isFixedPositionedContainer(currLayer)) {
1542 fixedPositionContainerLayer = currLayer;
1543 ASSERT_UNUSED(foundAncestor, foundAncestor);
1548 ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1550 if (fixedPositionContainerLayer != ancestorLayer) {
1551 LayoutPoint fixedContainerCoords;
1552 layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1554 LayoutPoint ancestorCoords;
1555 ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1557 location += (fixedContainerCoords - ancestorCoords);
1559 location += toSize(layer->location());
1561 return ancestorLayer;
1564 RenderLayer* parentLayer;
1565 if (position == AbsolutePosition || position == FixedPosition) {
1566 // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
1567 parentLayer = layer->parent();
1568 bool foundAncestorFirst = false;
1569 while (parentLayer) {
1570 // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
1571 // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
1572 // we are bailing out before reaching root layer.
1573 if (parentLayer->isPositionedContainer())
1576 if (parentLayer == ancestorLayer) {
1577 foundAncestorFirst = true;
1581 parentLayer = parentLayer->parent();
1584 // We should not reach RenderView layer past the RenderFlowThread layer for any
1585 // children of the RenderFlowThread.
1586 if (renderer->flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread())
1587 ASSERT(parentLayer != renderer->view()->layer());
1589 if (foundAncestorFirst) {
1590 // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
1591 // to enclosingPositionedAncestor and subtract.
1592 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
1594 LayoutPoint thisCoords;
1595 layer->convertToLayerCoords(positionedAncestor, thisCoords);
1597 LayoutPoint ancestorCoords;
1598 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
1600 location += (thisCoords - ancestorCoords);
1601 return ancestorLayer;
1604 parentLayer = layer->parent();
1609 location += toSize(layer->location());
1613 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
1615 if (ancestorLayer == this)
1618 const RenderLayer* currLayer = this;
1619 while (currLayer && currLayer != ancestorLayer)
1620 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location);
1623 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
1626 convertToLayerCoords(ancestorLayer, delta);
1627 rect.move(-delta.x(), -delta.y());
1630 RenderLayer* RenderLayer::scrollParent() const
1632 if (!renderer()->compositorDrivenAcceleratedScrollingEnabled())
1635 // Normal flow elements will be parented under the main scrolling layer, so
1636 // we don't need a scroll parent/child relationship to get them to scroll.
1637 if (stackingNode()->isNormalFlowOnly())
1640 // A layer scrolls with its containing block. So to find the overflow scrolling layer
1641 // that we scroll with respect to, we must ascend the layer tree until we reach the
1642 // first overflow scrolling div at or above our containing block. I will refer to this
1643 // layer as our 'scrolling ancestor'.
1645 // Now, if we reside in a normal flow list, then we will naturally scroll with our scrolling
1646 // ancestor, and we need not be composited. If, on the other hand, we reside in a z-order
1647 // list, and on our walk upwards to our scrolling ancestor we find no layer that is a stacking
1648 // context, then we know that in the stacking tree, we will not be in the subtree rooted at
1649 // our scrolling ancestor, and we will therefore not scroll with it. In this case, we must
1650 // be a composited layer since the compositor will need to take special measures to ensure
1651 // that we scroll with our scrolling ancestor and it cannot do this if we do not promote.
1652 RenderLayer* scrollParent = ancestorCompositedScrollingLayer();
1654 if (!scrollParent || scrollParent->stackingNode()->isStackingContainer())
1657 // If we hit a stacking context on our way up to the ancestor scrolling layer, it will already
1658 // be composited due to an overflow scrolling parent, so we don't need to.
1659 for (RenderLayer* ancestor = parent(); ancestor && ancestor != scrollParent; ancestor = ancestor->parent()) {
1660 if (ancestor->stackingNode()->isStackingContainer())
1664 return scrollParent;
1667 RenderLayer* RenderLayer::clipParent() const
1669 const bool needsAncestorClip = compositor()->clippedByAncestor(this);
1671 RenderLayer* clipParent = 0;
1672 if ((compositingReasons() & CompositingReasonOutOfFlowClipping) && !needsAncestorClip) {
1673 if (RenderObject* containingBlock = renderer()->containingBlock())
1674 clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer();
1680 void RenderLayer::didUpdateNeedsCompositedScrolling()
1682 m_stackingNode->updateIsNormalFlowOnly();
1683 updateSelfPaintingLayer();
1685 if (m_stackingNode->isStackingContainer())
1686 m_stackingNode->dirtyZOrderLists();
1688 m_stackingNode->clearZOrderLists();
1690 m_stackingNode->dirtyStackingContainerZOrderLists();
1692 compositor()->setNeedsToRecomputeCompositingRequirements();
1693 compositor()->setCompositingLayersNeedRebuild();
1696 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle)
1698 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle));
1699 if (renderer()->hasReflection()) {
1700 if (!m_reflectionInfo)
1701 m_reflectionInfo = adoptPtr(new RenderLayerReflectionInfo(toRenderBox(renderer())));
1702 m_reflectionInfo->updateAfterStyleChange(oldStyle);
1703 } else if (m_reflectionInfo) {
1704 m_reflectionInfo = nullptr;
1708 void RenderLayer::updateStackingNode()
1710 if (requiresStackingNode())
1711 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this));
1713 m_stackingNode = nullptr;
1716 void RenderLayer::updateScrollableArea()
1718 if (requiresScrollableArea())
1719 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(renderBox()));
1721 m_scrollableArea = nullptr;
1724 PassOwnPtr<Vector<FloatRect> > RenderLayer::collectTrackedRepaintRects() const
1726 if (hasCompositedLayerMapping())
1727 return compositedLayerMapping()->collectTrackedRepaintRects();
1731 bool RenderLayer::hasOverflowControls() const
1733 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE);
1736 void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, PaintLayerFlags paintFlags)
1738 OverlapTestRequestMap overlapTestRequests;
1740 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot, &overlapTestRequests);
1741 paintLayer(context, paintingInfo, paintFlags);
1743 OverlapTestRequestMap::iterator end = overlapTestRequests.end();
1744 for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
1745 it->key->setIsOverlapped(false);
1748 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
1750 if (!m_containsDirtyOverlayScrollbars)
1753 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
1754 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars);
1756 m_containsDirtyOverlayScrollbars = false;
1759 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
1761 if (startLayer == endLayer)
1764 RenderView* view = startLayer->renderer()->view();
1765 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) {
1766 if (currentBlock->layer() == endLayer)
1773 void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect,
1774 BorderRadiusClippingRule rule)
1776 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
1779 context->clip(pixelSnappedIntRect(clipRect.rect()));
1781 if (!clipRect.hasRadius())
1784 // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
1785 // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
1786 // containing block chain so we check that also.
1787 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
1788 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
1790 layer->convertToLayerCoords(rootLayer, delta);
1791 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
1794 if (layer == rootLayer)
1799 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
1801 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
1806 static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
1808 Vector<RenderWidget*> overlappedRequestClients;
1809 OverlapTestRequestMap::iterator end = overlapTestRequests.end();
1810 LayoutRect boundingBox = layer->boundingBox(rootLayer);
1811 for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
1812 if (!boundingBox.intersects(it->value))
1815 it->key->setIsOverlapped(true);
1816 overlappedRequestClients.append(it->key);
1818 for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
1819 overlapTestRequests.remove(overlappedRequestClients[i]);
1822 static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
1824 return paintingReflection && !layer->has3DTransform();
1827 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
1829 // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
1830 // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
1831 // will do a full repaint().
1832 if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isRoot())
1838 static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags)
1840 return layer->renderer()->isRoot() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
1843 void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1845 // https://code.google.com/p/chromium/issues/detail?id=343772
1846 DisableCompositingQueryAsserts disabler;
1848 if (compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking) {
1849 // The updatingControlTints() painting pass goes through compositing layers,
1850 // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
1851 if (context->updatingControlTints() || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)) {
1852 paintFlags |= PaintLayerTemporaryClipRects;
1853 } else if (!compositedLayerMapping()->paintsIntoCompositedAncestor()
1854 && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)
1855 && !paintForFixedRootBackground(this, paintFlags)) {
1856 // If this RenderLayer should paint into its own backing, that will be done via CompositedLayerMapping::paintIntoLayer().
1859 } else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
1860 // Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible
1861 // unless their position or viewport size is changed.
1865 // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
1866 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
1869 if (shouldSuppressPaintingLayer(this))
1872 // If this layer is totally invisible then there is nothing to paint.
1873 if (!renderer()->opacity())
1876 if (paintsWithTransparency(paintingInfo.paintBehavior))
1877 paintFlags |= PaintLayerHaveTransparency;
1879 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice.
1880 if (paintsWithTransform(paintingInfo.paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
1881 TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior);
1882 // If the transform can't be inverted, then don't paint anything.
1883 if (!layerTransform.isInvertible())
1886 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
1887 // layer from the parent now, assuming there is a parent
1888 if (paintFlags & PaintLayerHaveTransparency) {
1890 parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
1892 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
1895 if (enclosingPaginationLayer()) {
1896 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags);
1900 // Make sure the parent's clip rects have been calculated.
1901 ClipRect clipRect = paintingInfo.paintDirtyRect;
1903 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
1904 IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
1905 clipRect = clipper().backgroundClipRect(clipRectsContext);
1906 clipRect.intersect(paintingInfo.paintDirtyRect);
1908 // Push the parent coordinate space's clip.
1909 parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
1912 paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
1914 // Restore the clip.
1916 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
1921 paintLayerContentsAndReflection(context, paintingInfo, paintFlags);
1924 void RenderLayer::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1926 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1928 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
1930 // Paint the reflection first if we have one.
1931 if (m_reflectionInfo)
1932 m_reflectionInfo->paint(context, paintingInfo, localPaintFlags | PaintLayerPaintingReflection);
1934 localPaintFlags |= PaintLayerPaintingCompositingAllPhases;
1935 paintLayerContents(context, paintingInfo, localPaintFlags);
1938 void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
1940 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1941 ASSERT(!(paintFlags & PaintLayerAppliedTransform));
1943 bool haveTransparency = paintFlags & PaintLayerHaveTransparency;
1944 bool isSelfPaintingLayer = this->isSelfPaintingLayer();
1945 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
1946 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase;
1947 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase;
1948 bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase;
1949 bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents;
1950 // Outline always needs to be painted even if we have no visible content. Also,
1951 // the outline is painted in the background phase during composited scrolling.
1952 // If it were painted in the foreground phase, it would move with the scrolled
1953 // content. When not composited scrolling, the outline is painted in the
1954 // foreground phase. Since scrolled contents are moved by repainting in this
1955 // case, the outline won't get 'dragged along'.
1956 bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
1957 && ((isPaintingScrollingContent && isPaintingCompositedBackground)
1958 || (!isPaintingScrollingContent && isPaintingCompositedForeground));
1959 bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
1961 float deviceScaleFactor = WebCore::deviceScaleFactor(renderer()->frame());
1962 context->setUseHighResMarkers(deviceScaleFactor > 1.5f);
1964 GraphicsContext* transparencyLayerContext = context;
1966 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot())
1969 // Ensure our lists are up-to-date.
1970 m_stackingNode->updateLayerListsIfNeeded();
1972 LayoutPoint offsetFromRoot;
1973 convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
1975 if (compositingState() == PaintsIntoOwnBacking)
1976 offsetFromRoot.move(m_compositedLayerMapping->subpixelAccumulation());
1978 LayoutRect rootRelativeBounds;
1979 bool rootRelativeBoundsComputed = false;
1981 // Apply clip-path to context.
1982 bool hasClipPath = false;
1983 RenderStyle* style = renderer()->style();
1984 RenderSVGResourceClipper* resourceClipper = 0;
1985 ClipperContext clipperContext;
1986 if (renderer()->hasClipPath() && !context->paintingDisabled() && style) {
1987 ASSERT(style->clipPath());
1988 if (style->clipPath()->type() == ClipPathOperation::SHAPE) {
1991 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath());
1993 if (!rootRelativeBoundsComputed) {
1994 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
1995 rootRelativeBoundsComputed = true;
1998 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule());
1999 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) {
2000 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath());
2001 Document& document = renderer()->document();
2002 // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
2003 Element* element = document.getElementById(referenceClipPathOperation->fragment());
2004 if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) {
2005 if (!rootRelativeBoundsComputed) {
2006 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
2007 rootRelativeBoundsComputed = true;
2010 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer()));
2011 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativeBounds,
2012 paintingInfo.paintDirtyRect, context, clipperContext)) {
2013 // No need to post-apply the clipper if this failed.
2014 resourceClipper = 0;
2020 // Blending operations must be performed only with the nearest ancestor stacking context.
2021 // Note that there is no need to create a transparency layer if we're painting the root.
2022 bool createTransparencyLayerForBlendMode = !renderer()->isRoot() && m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
2024 if (createTransparencyLayerForBlendMode)
2025 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
2027 LayerPaintingInfo localPaintingInfo(paintingInfo);
2028 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
2029 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
2030 RenderLayerFilterInfo* filterInfo = this->filterInfo();
2032 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
2033 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
2035 if (!rootRelativeBoundsComputed)
2036 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
2038 if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect, filterRepaintRect)) {
2039 // Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero.
2040 filterInfo->resetDirtySourceRect();
2042 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
2043 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
2044 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that
2045 // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method.
2046 context = filterPainter.beginFilterEffect(context);
2048 // Check that we didn't fail to allocate the graphics context for the offscreen buffer.
2049 if (filterPainter.hasStartedFilterEffect()) {
2050 localPaintingInfo.paintDirtyRect = filterPainter.repaintRect();
2051 // If the filter needs the full source image, we need to avoid using the clip rectangles.
2052 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
2053 // Note that we will still apply the clipping on the final rendering of the filter.
2054 localPaintingInfo.clipToDirtyRect = !filterRenderer()->hasFilterThatMovesPixels();
2059 if (filterPainter.hasStartedFilterEffect() && haveTransparency) {
2060 // 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.
2061 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
2064 // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
2065 // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
2066 // Else, our renderer tree may or may not contain the painting root, so we pass that root along
2067 // so it will be tested against as we descend through the renderers.
2068 RenderObject* paintingRootForRenderer = 0;
2069 if (localPaintingInfo.paintingRoot && !renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
2070 paintingRootForRenderer = localPaintingInfo.paintingRoot;
2072 if (localPaintingInfo.overlapTestRequests && isSelfPaintingLayer)
2073 performOverlapTests(*localPaintingInfo.overlapTestRequests, localPaintingInfo.rootLayer, this);
2075 bool forceBlackText = localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText;
2076 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
2078 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
2079 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground);
2080 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent;
2081 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground;
2082 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars;
2083 bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly;
2084 bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly;
2086 PaintBehavior paintBehavior = PaintBehaviorNormal;
2087 if (paintFlags & PaintLayerPaintingSkipRootBackground)
2088 paintBehavior |= PaintBehaviorSkipRootBackground;
2089 else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
2090 paintBehavior |= PaintBehaviorRootBackgroundOnly;
2092 LayerFragments layerFragments;
2093 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
2094 // 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
2095 // fragment should paint.
2096 collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
2097 (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
2098 (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
2099 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
2102 if (shouldPaintBackground)
2103 paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
2104 localPaintingInfo, paintBehavior, paintingRootForRenderer);
2106 if (shouldPaintNegZOrderList)
2107 paintChildren(NegativeZOrderChildren, context, localPaintingInfo, paintFlags);
2109 if (shouldPaintOwnContents)
2110 paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
2111 localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, forceBlackText);
2113 if (shouldPaintOutline)
2114 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer);
2116 if (shouldPaintNormalFlowAndPosZOrderLists)
2117 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, localPaintingInfo, paintFlags);
2119 if (shouldPaintOverlayScrollbars)
2120 paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo);
2122 if (filterPainter.hasStartedFilterEffect()) {
2123 // Apply the correct clipping (ie. overflow: hidden).
2124 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
2125 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
2126 clipToRect(localPaintingInfo.rootLayer, transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
2127 context = filterPainter.applyFilterEffect();
2128 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
2131 // Make sure that we now use the original transparency context.
2132 ASSERT(transparencyLayerContext == context);
2134 if (shouldPaintMask)
2135 paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
2137 if (shouldPaintClippingMask) {
2138 // Paint the border radius mask for the fragments.
2139 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
2142 // End our transparency layer
2143 if ((haveTransparency || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency && !(m_reflectionInfo && m_reflectionInfo->isPaintingInsideReflection())) {
2144 context->endLayer();
2146 m_usedTransparency = false;
2149 if (resourceClipper)
2150 resourceClipper->postApplyStatefulResource(renderer(), context, clipperContext);
2156 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset)
2158 // This involves subtracting out the position of the layer in our current coordinate space, but preserving
2159 // the accumulated error for sub-pixel layout.
2161 convertToLayerCoords(paintingInfo.rootLayer, delta);
2162 delta.moveBy(translationOffset);
2163 TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
2164 IntPoint roundedDelta = roundedIntPoint(delta);
2165 transform.translateRight(roundedDelta.x(), roundedDelta.y());
2166 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
2168 // Apply the transform.
2169 GraphicsContextStateSaver stateSaver(*context, false);
2170 if (!transform.isIdentity()) {
2172 context->concatCTM(transform.toAffineTransform());
2175 // Now do a paint with the root layer shifted to be us.
2176 LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior,
2177 adjustedSubPixelAccumulation, paintingInfo.paintingRoot, paintingInfo.overlapTestRequests);
2178 paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
2181 void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2183 if (!hasSelfPaintingLayerDescendant())
2186 #if !ASSERT_DISABLED
2187 LayerListMutationDetector mutationChecker(m_stackingNode.get());
2190 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit);
2191 while (RenderLayerStackingNode* child = iterator.next()) {
2192 RenderLayer* childLayer = child->layer();
2194 // Squashed RenderLayers should not paint into their ancestor.
2195 if (childLayer->compositingState() == PaintsIntoGroupedBacking)
2198 if (!childLayer->isPaginated())
2199 childLayer->paintLayer(context, paintingInfo, paintFlags);
2201 paintPaginatedChildLayer(childLayer, context, paintingInfo, paintFlags);
2205 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
2206 ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
2207 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
2209 if (!enclosingPaginationLayer() || hasTransform()) {
2210 // For unpaginated layers, there is only one fragment.
2211 LayerFragment fragment;
2212 ClipRectsContext clipRectsContext(rootLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip, subPixelAccumulation);
2213 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
2214 fragments.append(fragment);
2218 // Compute our offset within the enclosing pagination layer.
2219 LayoutPoint offsetWithinPaginatedLayer;
2220 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer);
2222 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
2223 // 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.
2224 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
2225 LayoutRect layerBoundsInFlowThread;
2226 ClipRect backgroundRectInFlowThread;
2227 ClipRect foregroundRectInFlowThread;
2228 ClipRect outlineRectInFlowThread;
2229 clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
2230 outlineRectInFlowThread, &offsetWithinPaginatedLayer);
2232 // Take our bounding box within the flow thread and clip it.
2233 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer);
2234 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
2236 // Shift the dirty rect into flow thread coordinates.
2237 LayoutPoint offsetOfPaginationLayerFromRoot;
2238 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
2239 LayoutRect dirtyRectInFlowThread(dirtyRect);
2240 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot);
2242 // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
2243 // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
2244 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
2245 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
2247 if (fragments.isEmpty())
2250 // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
2251 ClipRect ancestorClipRect = dirtyRect;
2252 if (enclosingPaginationLayer()->parent()) {
2253 ClipRectsContext clipRectsContext(rootLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
2254 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
2255 ancestorClipRect.intersect(dirtyRect);
2258 for (size_t i = 0; i < fragments.size(); ++i) {
2259 LayerFragment& fragment = fragments.at(i);
2261 // Set our four rects with all clipping applied that was internal to the flow thread.
2262 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread);
2264 // Shift to the root-relative physical position used when painting the flow thread in this fragment.
2265 fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2267 // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
2268 // properly clipped by the overflow.
2269 fragment.intersect(ancestorClipRect.rect());
2271 // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
2272 // clip, so the column clip ends up being all we apply.
2273 fragment.intersect(fragment.paginationClip);
2277 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags,
2278 bool shouldPaintContent, const LayoutPoint* offsetFromRoot)
2280 ASSERT(offsetFromRoot);
2281 for (size_t i = 0; i < fragments.size(); ++i) {
2282 LayerFragment& fragment = fragments.at(i);
2283 fragment.shouldPaintContent = shouldPaintContent;
2284 if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) {
2285 LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset;
2286 fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot);
2291 void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2293 LayerFragments enclosingPaginationFragments;
2294 LayoutPoint offsetOfPaginationLayerFromRoot;
2295 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior);
2296 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
2297 (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
2298 (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent);
2300 for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
2301 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
2303 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
2304 // the enclosing pagination layer.
2305 LayoutRect clipRect = fragment.backgroundRect.rect();
2307 // Now compute the clips within a given fragment
2308 if (parent() != enclosingPaginationLayer()) {
2309 enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot);
2311 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
2312 IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
2313 LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
2314 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2315 clipRect.intersect(parentClipRect);
2318 parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
2319 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
2320 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
2324 static inline LayoutSize subPixelAccumulationIfNeeded(const LayoutSize& subPixelAccumulation, CompositingState compositingState)
2326 // Only apply the sub-pixel accumulation if we don't paint into our own backing layer, otherwise the position
2327 // of the renderer already includes any sub-pixel offset.
2328 if (compositingState == PaintsIntoOwnBacking)
2329 return LayoutSize();
2330 return subPixelAccumulation;
2333 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
2334 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
2335 RenderObject* paintingRootForRenderer)
2337 for (size_t i = 0; i < layerFragments.size(); ++i) {
2338 const LayerFragment& fragment = layerFragments.at(i);
2339 if (!fragment.shouldPaintContent)
2342 // Begin transparency layers lazily now that we know we have to paint something.
2343 if (haveTransparency || paintsWithBlendMode())
2344 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
2346 if (localPaintingInfo.clipToDirtyRect) {
2347 // Paint our background first, before painting any child layers.
2348 // Establish the clip used to paint our background.
2349 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
2352 // Paint the background.
2353 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
2354 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
2355 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2357 if (localPaintingInfo.clipToDirtyRect)
2358 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2362 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
2363 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
2364 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackText)
2366 // Begin transparency if we have something to paint.
2367 if (haveTransparency || paintsWithBlendMode()) {
2368 for (size_t i = 0; i < layerFragments.size(); ++i) {
2369 const LayerFragment& fragment = layerFragments.at(i);
2370 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
2371 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
2377 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBehaviorForceBlackText : paintBehavior;
2379 // Optimize clipping for the single fragment case.
2380 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
2382 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
2384 // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
2385 // interleaving of the fragments to work properly.
2386 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments,
2387 context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
2389 if (!selectionOnly) {
2390 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
2391 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
2392 paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
2396 restoreClip(context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
2399 void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context,
2400 const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer)
2402 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1;
2404 for (size_t i = 0; i < layerFragments.size(); ++i) {
2405 const LayerFragment& fragment = layerFragments.at(i);
2406 if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty())
2410 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2412 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
2413 if (phase == PaintPhaseForeground)
2414 paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
2415 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2418 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2422 void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2423 PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer)
2425 for (size_t i = 0; i < layerFragments.size(); ++i) {
2426 const LayerFragment& fragment = layerFragments.at(i);
2427 if (fragment.outlineRect.isEmpty())
2430 // Paint our own outline
2431 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
2432 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
2433 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2434 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
2438 void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2439 RenderObject* paintingRootForRenderer)
2441 for (size_t i = 0; i < layerFragments.size(); ++i) {
2442 const LayerFragment& fragment = layerFragments.at(i);
2443 if (!fragment.shouldPaintContent)
2446 if (localPaintingInfo.clipToDirtyRect)
2447 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
2450 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
2451 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
2452 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2454 if (localPaintingInfo.clipToDirtyRect)
2455 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2459 void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
2460 RenderObject* paintingRootForRenderer)
2462 for (size_t i = 0; i < layerFragments.size(); ++i) {
2463 const LayerFragment& fragment = layerFragments.at(i);
2464 if (!fragment.shouldPaintContent)
2467 if (localPaintingInfo.clipToDirtyRect)
2468 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
2470 // Paint the the clipped mask.
2471 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
2472 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
2474 if (localPaintingInfo.clipToDirtyRect)
2475 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
2479 void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo)
2481 for (size_t i = 0; i < layerFragments.size(); ++i) {
2482 const LayerFragment& fragment = layerFragments.at(i);
2483 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2484 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
2485 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
2486 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
2490 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
2492 // We need to do multiple passes, breaking up our child layer into strips.
2493 Vector<RenderLayer*> columnLayers;
2494 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode();
2495 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
2496 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
2497 columnLayers.append(curr);
2498 if (curr->stackingNode() == ancestorNode)
2502 // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before
2503 // updateLayerPositions() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
2504 // If this is the case, just bail out, since the upcoming call to updateLayerPositions() will repaint the layer.
2505 if (!columnLayers.size())
2508 paintChildLayerIntoColumns(childLayer, context, paintingInfo, paintFlags, columnLayers, columnLayers.size() - 1);
2511 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo,
2512 PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex)
2514 RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer());
2516 ASSERT(columnBlock && columnBlock->hasColumns());
2517 if (!columnBlock || !columnBlock->hasColumns())
2520 LayoutPoint layerOffset;
2521 // FIXME: It looks suspicious to call convertToLayerCoords here
2522 // as canUseConvertToLayerCoords is true for this layer.
2523 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffset);
2525 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
2527 ColumnInfo* colInfo = columnBlock->columnInfo();
2528 unsigned colCount = columnBlock->columnCount(colInfo);
2529 LayoutUnit currLogicalTopOffset = 0;
2530 for (unsigned i = 0; i < colCount; i++) {
2531 // For each rect, we clip to the rect, and then we adjust our coords.
2532 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2533 columnBlock->flipForWritingMode(colRect);
2534 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
2537 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2538 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset);
2540 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
2542 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2543 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset);
2545 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
2548 colRect.moveBy(layerOffset);
2550 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect);
2551 localDirtyRect.intersect(colRect);
2553 if (!localDirtyRect.isEmpty()) {
2554 GraphicsContextStateSaver stateSaver(*context);
2556 // Each strip pushes a clip, since column boxes are specified as being
2557 // like overflow:hidden.
2558 context->clip(pixelSnappedIntRect(colRect));
2561 // Apply a translation transform to change where the layer paints.
2562 TransformationMatrix oldTransform;
2563 bool oldHasTransform = childLayer->transform();
2564 if (oldHasTransform)
2565 oldTransform = *childLayer->transform();
2566 TransformationMatrix newTransform(oldTransform);
2567 newTransform.translateRight(roundToInt(offset.width()), roundToInt(offset.height()));
2569 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
2571 LayerPaintingInfo localPaintingInfo(paintingInfo);
2572 localPaintingInfo.paintDirtyRect = localDirtyRect;
2573 childLayer->paintLayer(context, localPaintingInfo, paintFlags);
2575 if (oldHasTransform)
2576 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
2578 childLayer->m_transform.clear();
2580 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
2581 // This involves subtracting out the position of the layer in our current coordinate space.
2582 LayoutPoint childOffset;
2583 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.rootLayer, childOffset);
2584 TransformationMatrix transform;
2585 transform.translateRight(roundToInt(childOffset.x() + offset.width()), roundToInt(childOffset.y() + offset.height()));
2587 // Apply the transform.
2588 context->concatCTM(transform.toAffineTransform());
2590 // Now do a paint with the root layer shifted to be the next multicol block.
2591 LayerPaintingInfo columnPaintingInfo(paintingInfo);
2592 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1];
2593 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(localDirtyRect);
2594 paintChildLayerIntoColumns(childLayer, context, columnPaintingInfo, paintFlags, columnLayers, colIndex - 1);
2598 // Move to the next position.
2599 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width();
2600 if (columnBlock->style()->isFlippedBlocksWritingMode())
2601 currLogicalTopOffset += blockDelta;
2603 currLogicalTopOffset -= blockDelta;
2607 static inline LayoutRect frameVisibleRect(RenderObject* renderer)
2609 FrameView* frameView = renderer->document().view();
2611 return LayoutRect();
2613 return frameView->visibleContentRect();
2616 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
2618 return hitTest(request, result.hitTestLocation(), result);
2621 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result)
2623 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
2625 // RenderView should make sure to update layout before entering hit testing
2626 ASSERT(!renderer()->frame()->view()->layoutPending());
2627 ASSERT(!renderer()->document().renderer()->needsLayout());
2629 LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect();
2630 if (!request.ignoreClipping())
2631 hitTestArea.intersect(frameVisibleRect(renderer()));
2633 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hitTestLocation, false);
2635 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
2636 // return ourselves. We do this so mouse events continue getting delivered after a drag has
2637 // exited the WebView, and so hit testing over a scrollbar hits the content document.
2638 if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) {
2639 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point()));
2644 // Now determine if the result is inside an anchor - if the urlElement isn't already set.
2645 Node* node = result.innerNode();
2646 if (node && !result.URLElement())
2647 result.setURLElement(toElement(node->enclosingLinkEventParentOrSelf()));
2649 // Now return whether we were inside this layer (this will always be true for the root
2654 Node* RenderLayer::enclosingElement() const
2656 for (RenderObject* r = renderer(); r; r = r->parent()) {
2657 if (Node* e = r->node())
2660 ASSERT_NOT_REACHED();
2664 bool RenderLayer::isInTopLayer() const
2666 Node* node = renderer()->node();
2667 return node && node->isElementNode() && toElement(node)->isInTopLayer();
2670 bool RenderLayer::isInTopLayerSubtree() const
2672 for (const RenderLayer* layer = this; layer; layer = layer->parent()) {
2673 if (layer->isInTopLayer())
2679 // Compute the z-offset of the point in the transformState.
2680 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
2681 // ray intersects target, and computing the z delta between those two points.
2682 static double computeZOffset(const HitTestingTransformState& transformState)
2684 // We got an affine transform, so no z-offset
2685 if (transformState.m_accumulatedTransform.isAffine())
2688 // Flatten the point into the target plane
2689 FloatPoint targetPoint = transformState.mappedPoint();
2691 // Now map the point back through the transform, which computes Z.
2692 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
2693 return backmappedPoint.z();
2696 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
2697 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
2698 const HitTestingTransformState* containerTransformState,
2699 const LayoutPoint& translationOffset) const
2701 RefPtr<HitTestingTransformState> transformState;
2703 if (containerTransformState) {
2704 // If we're already computing transform state, then it's relative to the container (which we know is non-null).
2705 transformState = HitTestingTransformState::create(*containerTransformState);
2706 convertToLayerCoords(containerLayer, offset);
2708 // If this is the first time we need to make transform state, then base it off of hitTestLocation,
2709 // which is relative to rootLayer.
2710 transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect));
2711 convertToLayerCoords(rootLayer, offset);
2713 offset.moveBy(translationOffset);
2715 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
2716 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
2717 TransformationMatrix containerTransform;
2718 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform);
2719 transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
2721 transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform);
2724 return transformState;
2728 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
2733 // The hit layer is depth-sorting with other layers, so just say that it was hit.
2737 // We need to look at z-depth to decide if this layer was hit.
2739 ASSERT(transformState);
2740 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
2741 double childZOffset = computeZOffset(*transformState);
2742 if (childZOffset > *zOffset) {
2743 *zOffset = childZOffset;
2752 // hitTestLocation and hitTestRect are relative to rootLayer.
2753 // A 'flattening' layer is one preserves3D() == false.
2754 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
2755 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer.
2756 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
2758 // If zOffset is non-null (which indicates that the caller wants z offset information),
2759 // *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
2760 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2761 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform,
2762 const HitTestingTransformState* transformState, double* zOffset)
2764 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
2767 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
2769 // Apply a transform if we have one.
2770 if (transform() && !appliedTransform) {
2771 if (enclosingPaginationLayer())
2772 return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
2774 // Make sure the parent's clip rects have been calculated.
2776 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize);
2777 ClipRect clipRect = clipper().backgroundClipRect(clipRectsContext);
2778 // Go ahead and test the enclosing clip now.
2779 if (!clipRect.intersects(hitTestLocation))
2783 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
2786 // Ensure our lists and 3d status are up-to-date.
2787 m_stackingNode->updateLayerListsIfNeeded();
2788 update3DTransformedDescendantStatus();
2790 RefPtr<HitTestingTransformState> localTransformState;
2791 if (appliedTransform) {
2792 // We computed the correct state in the caller (above code), so just reference it.
2793 ASSERT(transformState);
2794 localTransformState = const_cast<HitTestingTransformState*>(transformState);
2795 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
2796 // We need transform state for the first time, or to offset the container state, so create it here.
2797 localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
2800 // Check for hit test on backface if backface-visibility is 'hidden'
2801 if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
2802 TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
2803 // If the z-vector of the matrix is negative, the back is facing towards the viewer.
2804 if (invertedMatrix.m33() < 0)
2808 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
2809 if (localTransformState && !preserves3D()) {
2810 // Keep a copy of the pre-flattening state, for computing z-offsets for the container
2811 unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
2812 // This layer is flattening, so flatten the state passed to descendants.
2813 localTransformState->flatten();
2816 // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
2818 double localZOffset = -numeric_limits<double>::infinity();
2819 double* zOffsetForDescendantsPtr = 0;
2820 double* zOffsetForContentsPtr = 0;
2822 bool depthSortDescendants = false;
2823 if (preserves3D()) {
2824 depthSortDescendants = true;
2825 // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
2826 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
2827 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
2828 } else if (m_has3DTransformedDescendant) {
2829 // Flattening layer with 3d children; use a local zOffset pointer to depth-test children and foreground.
2830 depthSortDescendants = true;
2831 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
2832 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
2833 } else if (zOffset) {
2834 zOffsetForDescendantsPtr = 0;
2835 // Container needs us to give back a z offset for the hit layer.
2836 zOffsetForContentsPtr = zOffset;
2839 // This variable tracks which layer the mouse ends up being inside.
2840 RenderLayer* candidateLayer = 0;
2842 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
2843 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2844 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2846 if (!depthSortDescendants)
2848 candidateLayer = hitLayer;
2851 // Now check our overflow objects.
2852 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2853 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2855 if (!depthSortDescendants)
2857 candidateLayer = hitLayer;
2860 // Collect the fragments. This will compute the clip rectangles for each layer fragment.
2861 LayerFragments layerFragments;
2862 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
2864 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) {
2865 renderer()->updateHitTestResult(result, hitTestLocation.point());
2869 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check
2870 // every fragment in reverse order.
2871 if (isSelfPaintingLayer()) {
2872 // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
2873 HitTestResult tempResult(result.hitTestLocation());
2874 bool insideFragmentForegroundRect = false;
2875 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect)
2876 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
2877 if (result.isRectBasedTest())
2878 result.append(tempResult);
2880 result = tempResult;
2881 if (!depthSortDescendants)
2883 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
2884 candidateLayer = this;
2885 } else if (insideFragmentForegroundRect && result.isRectBasedTest())
2886 result.append(tempResult);
2889 // Now check our negative z-index children.
2890 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
2891 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
2893 if (!depthSortDescendants)
2895 candidateLayer = hitLayer;
2898 // If we found a layer, return. Child layers, and foreground always render in front of background.
2900 return candidateLayer;
2902 if (isSelfPaintingLayer()) {
2903 HitTestResult tempResult(result.hitTestLocation());
2904 bool insideFragmentBackgroundRect = false;
2905 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect)
2906 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
2907 if (result.isRectBasedTest())
2908 result.append(tempResult);
2910 result = tempResult;
2913 if (insideFragmentBackgroundRect && result.isRectBasedTest())
2914 result.append(tempResult);
2920 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result,
2921 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const
2923 if (layerFragments.isEmpty())
2926 for (int i = layerFragments.size() - 1; i >= 0; --i) {
2927 const LayerFragment& fragment = layerFragments.at(i);
2928 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation))
2929 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation)))
2931 insideClipRect = true;
2932 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter))
2939 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2940 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2942 LayerFragments enclosingPaginationFragments;
2943 LayoutPoint offsetOfPaginationLayerFromRoot;
2944 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox);
2945 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
2946 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
2948 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
2949 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
2951 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
2952 // the enclosing pagination layer.
2953 LayoutRect clipRect = fragment.backgroundRect.rect();
2955 // Now compute the clips within a given fragment
2956 if (parent() != enclosingPaginationLayer()) {
2957 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
2959 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize);
2960 LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
2961 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
2962 clipRect.intersect(parentClipRect);
2965 if (!hitTestLocation.intersects(clipRect))
2968 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation,
2969 transformState, zOffset, fragment.paginationOffset);
2977 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
2978 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
2979 const LayoutPoint& translationOffset)
2981 // Create a transform state to accumulate this transform.
2982 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset);
2984 // If the transform can't be inverted, then don't hit test this layer at all.
2985 if (!newTransformState->m_accumulatedTransform.isInvertible())
2988 // Compute the point and the hit test rect in the coords of this layer by using the values
2989 // from the transformState, which store the point and quad in the coords of the last flattened
2990 // layer, and the accumulated transform which lets up map through preserve-3d layers.
2992 // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z)
2993 // by our container.
2994 FloatPoint localPoint = newTransformState->mappedPoint();
2995 FloatQuad localPointQuad = newTransformState->mappedQuad();
2996 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea();
2997 HitTestLocation newHitTestLocation;
2998 if (hitTestLocation.isRectBasedTest())
2999 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
3001 newHitTestLocation = HitTestLocation(localPoint);
3003 // Now do a hit test with the root layer shifted to be us.
3004 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset);
3007 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const
3009 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
3011 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) {
3012 // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
3013 // a rect-based test.
3014 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
3018 // For positioned generated content, we might still not have a
3019 // node by the time we get to the layer level, since none of
3020 // the content in the layer has an element. So just walk up
3022 if (!result.innerNode() || !result.innerNonSharedNode()) {
3023 Node* e = enclosingElement();
3024 if (!result.innerNode())
3025 result.setInnerNode(e);
3026 if (!result.innerNonSharedNode())
3027 result.setInnerNonSharedNode(e);
3033 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer,
3034 const HitTestRequest& request, HitTestResult& result,
3035 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
3036 const HitTestingTransformState* transformState,
3037 double* zOffsetForDescendants, double* zOffset,
3038 const HitTestingTransformState* unflattenedTransformState,
3039 bool depthSortDescendants)
3041 if (!hasSelfPaintingLayerDescendant())
3044 RenderLayer* resultLayer = 0;
3045 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit);
3046 while (RenderLayerStackingNode* child = iterator.next()) {
3047 RenderLayer* childLayer = child->layer();
3048 RenderLayer* hitLayer = 0;
3049 HitTestResult tempResult(result.hitTestLocation());
3050 if (childLayer->isPaginated())
3051 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
3053 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
3055 // If it a rect-based test, we can safely append the temporary result since it might had hit
3056 // nodes but not necesserily had hitLayer set.
3057 if (result.isRectBasedTest())
3058 result.append(tempResult);
3060 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
3061 resultLayer = hitLayer;
3062 if (!result.isRectBasedTest())
3063 result = tempResult;
3064 if (!depthSortDescendants)
3072 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
3073 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
3075 Vector<RenderLayer*> columnLayers;
3076 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode();
3077 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
3078 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
3079 columnLayers.append(curr);
3080 if (curr->stackingNode() == ancestorNode)
3084 ASSERT(columnLayers.size());
3085 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset,
3086 columnLayers, columnLayers.size() - 1);
3089 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
3090 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
3091 const Vector<RenderLayer*>& columnLayers, size_t columnIndex)
3093 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer());
3095 ASSERT(columnBlock && columnBlock->hasColumns());
3096 if (!columnBlock || !columnBlock->hasColumns())
3099 LayoutPoint layerOffset;
3100 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
3102 ColumnInfo* colInfo = columnBlock->columnInfo();
3103 int colCount = columnBlock->columnCount(colInfo);
3105 // We have to go backwards from the last column to the first.
3106 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
3107 LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent();
3108 LayoutUnit currLogicalTopOffset = 0;
3110 for (i = 0; i < colCount; i++) {
3111 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
3112 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
3113 if (columnBlock->style()->isFlippedBlocksWritingMode())
3114 currLogicalTopOffset += blockDelta;
3116 currLogicalTopOffset -= blockDelta;
3118 for (i = colCount - 1; i >= 0; i--) {
3119 // For each rect, we clip to the rect, and then we adjust our coords.
3120 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
3121 columnBlock->flipForWritingMode(colRect);
3122 LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
3123 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
3124 if (columnBlock->style()->isFlippedBlocksWritingMode())
3125 currLogicalTopOffset -= blockDelta;
3127 currLogicalTopOffset += blockDelta;
3131 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3132 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset);
3134 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
3136 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3137 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset);
3139 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
3142 colRect.moveBy(layerOffset);
3144 LayoutRect localClipRect(hitTestRect);
3145 localClipRect.intersect(colRect);
3147 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect)) {
3148 RenderLayer* hitLayer = 0;
3150 // Apply a translation transform to change where the layer paints.
3151 TransformationMatrix oldTransform;
3152 bool oldHasTransform = childLayer->transform();
3153 if (oldHasTransform)
3154 oldTransform = *childLayer->transform();
3155 TransformationMatrix newTransform(oldTransform);
3156 newTransform.translateRight(offset.width(), offset.height());
3158 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
3159 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestLocation, false, transformState, zOffset);
3160 if (oldHasTransform)
3161 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
3163 childLayer->m_transform.clear();
3165 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space.
3166 // This involves subtracting out the position of the layer in our current coordinate space.
3167 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
3168 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation, transformState);
3169 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
3170 FloatPoint localPoint = newTransformState->mappedPoint();
3171 FloatQuad localPointQuad = newTransformState->mappedQuad();
3172 LayoutRect localHitTestRect = newTransformState->mappedArea().enclosingBoundingBox();
3173 HitTestLocation newHitTestLocation;
3174 if (hitTestLocation.isRectBasedTest())
3175 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
3177 newHitTestLocation = HitTestLocation(localPoint);
3178 newTransformState->flatten();
3180 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, newHitTestLocation,
3181 newTransformState.get(), zOffset, columnLayers, columnIndex - 1);
3192 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
3194 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
3197 void RenderLayer::clearBlockSelectionGapsBounds()
3199 m_blockSelectionGapsBounds = IntRect();
3200 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
3201 child->clearBlockSelectionGapsBounds();
3204 void RenderLayer::repaintBlockSelectionGaps()
3206 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
3207 child->repaintBlockSelectionGaps();
3209 if (m_blockSelectionGapsBounds.isEmpty())
3212 LayoutRect rect = m_blockSelectionGapsBounds;
3213 if (renderer()->hasOverflowClip()) {
3214 RenderBox* box = renderBox();
3215 rect.move(-box->scrolledContentOffset());
3216 if (!scrollableArea()->usesCompositedScrolling())
3217 rect.intersect(box->overflowClipRect(LayoutPoint()));
3219 if (renderer()->hasClip())
3220 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint()));
3221 if (!rect.isEmpty())
3222 renderer()->repaintRectangle(rect);
3225 bool RenderLayer::hasBlockSelectionGapBounds() const
3227 return !m_blockSelectionGapsBounds.isEmpty();
3230 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
3232 // Always examine the canvas and the root.
3233 // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
3234 // paints the root's background.
3235 if (isRootLayer() || renderer()->isRoot())
3238 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
3239 // can go ahead and return true.
3240 RenderView* view = renderer()->view();
3242 if (view && !renderer()->isRenderInline()) {
3243 LayoutRect b = layerBounds;
3244 b.inflate(view->maximalOutlineSize());
3245 if (b.intersects(damageRect))
3249 // Otherwise we need to compute the bounding box of this single layer and see if it intersects
3251 return boundingBox(rootLayer, 0, offsetFromRoot).intersects(damageRect);
3254 LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
3256 // There are three special cases we need to consider.
3257 // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
3258 // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the
3259 // line boxes of all three lines (including overflow on those lines).
3260 // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top
3261 // overflow, we have to create a bounding box that will extend to include this overflow.
3262 // (3) Floats. When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
3263 // as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
3266 if (renderer()->isInline() && renderer()->isRenderInline())
3267 result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
3268 else if (renderer()->isTableRow()) {
3269 // Our bounding box is just the union of all of our cells' border/overflow rects.
3270 for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
3271 if (child->isTableCell()) {
3272 LayoutRect bbox = toRenderBox(child)->borderBoxRect();
3274 LayoutRect overflowRect = renderBox()->visualOverflowRect();
3275 if (bbox != overflowRect)
3276 result.unite(overflowRect);
3280 RenderBox* box = renderBox();
3282 if (!(flags & DontConstrainForMask) && box->hasMask()) {
3283 result = box->maskClipRect();
3284 box->flipForWritingMode(result); // The mask clip rect is in physical coordinates, so we have to flip, since localBoundingBox is not.
3286 LayoutRect bbox = box->borderBoxRect();
3288 LayoutRect overflowRect = box->visualOverflowRect();
3289 if (bbox != overflowRect)
3290 result.unite(overflowRect);
3294 RenderView* view = renderer()->view();
3297 result.inflate(view->maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
3302 LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags flags, const LayoutPoint* offsetFromRoot) const
3304 LayoutRect result = localBoundingBox(flags);
3305 if (renderer()->isBox())
3306 renderBox()->flipForWritingMode(result);
3308 renderer()->containingBlock()->flipForWritingMode(result);
3310 if (enclosingPaginationLayer() && (flags & UseFragmentBoxes)) {
3311 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
3312 // get our true bounding box.
3313 LayoutPoint offsetWithinPaginationLayer;
3314 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginationLayer);
3315 result.moveBy(offsetWithinPaginationLayer);
3317 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
3318 result = enclosingFlowThread->fragmentsBoundingBox(result);
3322 delta = *offsetFromRoot;
3324 enclosingPaginationLayer()->convertToLayerCoords(ancestorLayer, delta);
3325 result.moveBy(delta);
3331 delta = *offsetFromRoot;
3333 convertToLayerCoords(ancestorLayer, delta);
3335 result.moveBy(delta);
3339 IntRect RenderLayer::absoluteBoundingBox() const
3341 return pixelSnappedIntRect(boundingBox(root()));
3344 LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const
3346 if (!isSelfPaintingLayer())
3347 return LayoutRect();
3349 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
3350 if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
3351 return LayoutRect();
3353 RenderLayerModelObject* renderer = this->renderer();
3355 if (isRootLayer()) {
3356 // The root layer is always just the size of the document.
3357 return renderer->view()->unscaledDocumentRect();
3360 LayoutRect boundingBoxRect = localBoundingBox(flags);
3362 if (renderer->isBox())
3363 toRenderBox(renderer)->flipForWritingMode(boundingBoxRect);
3365 renderer->containingBlock()->flipForWritingMode(boundingBoxRect);
3367 if (renderer->isRoot()) {
3368 // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
3369 // then it has to be big enough to cover the viewport in order to display the background. This is akin
3370 // to the code in RenderBox::paintRootBoxFillLayers().
3371 if (FrameView* frameView = renderer->view()->frameView()) {
3372 LayoutUnit contentsWidth = frameView->contentsWidth();
3373 LayoutUnit contentsHeight = frameView->contentsHeight();
3375 boundingBoxRect.setWidth(max(boundingBoxRect.width(), contentsWidth - boundingBoxRect.x()));
3376 boundingBoxRect.setHeight(max(boundingBoxRect.height(), contentsHeight - boundingBoxRect.y()));
3380 LayoutRect unionBounds = boundingBoxRect;
3382 bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (transform() && flags & PretendLayerHasOwnBacking);
3384 if (flags & UseLocalClipRectIfPossible) {
3385 LayoutRect localClipRect = clipper().localClipRect();
3386 if (localClipRect != PaintInfo::infiniteRect()) {
3387 if ((flags & IncludeSelfTransform) && shouldIncludeTransform)
3388 localClipRect = transform()->mapRect(localClipRect);
3390 LayoutPoint ancestorRelOffset;
3391 convertToLayerCoords(ancestorLayer, ancestorRelOffset);
3392 localClipRect.moveBy(ancestorRelOffset);
3393 return localClipRect;
3397 // FIXME: should probably just pass 'flags' down to descendants.
3398 CalculateLayerBoundsFlags descendantFlags = DefaultCalculateLayerBoundsFlags | (flags & ExcludeHiddenDescendants) | (flags & IncludeCompositedDescendants);
3400 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
3402 if (m_reflectionInfo) {
3403 RenderLayer* reflectionLayer = m_reflectionInfo->reflectionLayer();
3404 if (!reflectionLayer->hasCompositedLayerMapping()) {
3405 LayoutRect childUnionBounds = reflectionLayer->calculateLayerBounds(this, 0, descendantFlags);
3406 unionBounds.unite(childUnionBounds);
3410 ASSERT(m_stackingNode->isStackingContainer() || !m_stackingNode->hasPositiveZOrderList());
3412 #if !ASSERT_DISABLED
3413 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this)->stackingNode());
3416 // FIXME: Descendants that are composited should not necessarily be skipped, if they don't paint into their own
3417 // separate backing. Instead, they ought to contribute to the bounds of the layer we're trying to compute.
3418 // This applies to all z-order lists below.
3419 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), AllChildren);
3420 while (RenderLayerStackingNode* node = iterator.next()) {
3421 // Node's compositing ancestor may have changed its draw content status
3422 // prior to updating its bounds. The requires-own-backing-store-for-ancestor-reasons
3423 // could be stale. Refresh them now.
3424 if (node->layer()->hasCompositedLayerMapping()) {
3425 RenderLayer* enclosingCompositingLayer = node->layer()->enclosingCompositingLayer(ExcludeSelf);
3426 node->layer()->compositedLayerMapping()->updateRequiresOwnBackingStoreForAncestorReasons(enclosingCompositingLayer);
3429 if (flags & IncludeCompositedDescendants || !node->layer()->hasCompositedLayerMapping()) {
3430 LayoutRect childUnionBounds = node->layer()->calculateLayerBounds(this, 0, descendantFlags);
3431 unionBounds.unite(childUnionBounds);
3435 // FIXME: We can optimize the size of the composited layers, by not enlarging
3436 // filtered areas with the outsets if we know that the filter is going to render in hardware.
3437 // https://bugs.webkit.org/show_bug.cgi?id=81239
3438 if (flags & IncludeLayerFilterOutsets)
3439 renderer->style()->filterOutsets().expandRect(unionBounds);
3441 if ((flags & IncludeSelfTransform) && shouldIncludeTransform) {
3442 TransformationMatrix* affineTrans = transform();
3443 boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
3444 unionBounds = affineTrans->mapRect(unionBounds);
3447 LayoutPoint ancestorRelOffset;
3449 ancestorRelOffset = *offsetFromRoot;
3451 convertToLayerCoords(ancestorLayer, ancestorRelOffset);
3452 unionBounds.moveBy(ancestorRelOffset);
3457 CompositingState RenderLayer::compositingState() const
3459 ASSERT(isAllowedToQueryCompositingState());
3461 // This is computed procedurally so there is no redundant state variable that
3462 // can get out of sync from the real actual compositing state.
3464 if (m_groupedMapping) {
3465 ASSERT(compositor()->layerSquashingEnabled());
3466 ASSERT(!m_compositedLayerMapping);
3467 return PaintsIntoGroupedBacking;
3470 if (!m_compositedLayerMapping)
3471 return NotComposited;
3473 if (m_compositedLayerMapping && compositedLayerMapping()->paintsIntoCompositedAncestor())
3474 return HasOwnBackingButPaintsIntoAncestor;
3476 ASSERT(m_compositedLayerMapping);
3477 return PaintsIntoOwnBacking;
3480 bool RenderLayer::isAllowedToQueryCompositingState() const
3482 if (gCompositingQueryMode == CompositingQueriesAreAllowed)
3484 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
3487 CompositedLayerMappingPtr RenderLayer::ensureCompositedLayerMapping()
3489 if (!m_compositedLayerMapping) {
3490 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(this));
3492 updateOrRemoveFilterEffectRenderer();
3494 if (RuntimeEnabledFeatures::cssCompositingEnabled())
3495 compositedLayerMapping()->setBlendMode(m_blendInfo.blendMode());
3497 return m_compositedLayerMapping.get();
3500 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
3502 m_compositedLayerMapping.clear();
3504 if (!layerBeingDestroyed)
3505 updateOrRemoveFilterEffectRenderer();
3508 bool RenderLayer::hasCompositedMask() const
3510 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
3513 bool RenderLayer::hasCompositedClippingMask() const
3515 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer();
3518 bool RenderLayer::clipsCompositingDescendantsWithBorderRadius() const
3520 RenderStyle* style = renderer()->style();
3524 return compositor()->clipsCompositingDescendants(this) && style->hasBorderRadius();
3527 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
3529 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
3532 bool RenderLayer::paintsWithBlendMode() const
3534 // https://code.google.com/p/chromium/issues/detail?id=343759
3535 DisableCompositingQueryAsserts disabler;
3536 return m_blendInfo.hasBlendMode() && compositingState() != PaintsIntoOwnBacking;
3539 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
3541 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
3544 if (paintsWithTransparency(PaintBehaviorNormal))
3547 // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child
3548 // is visible and that child doesn't cover the entire rect.
3549 if (renderer()->style()->visibility() != VISIBLE)
3552 if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity())
3555 // FIXME: Handle simple transforms.
3556 if (paintsWithTransform(PaintBehaviorNormal))
3559 // FIXME: Remove this check.
3560 // This function should not be called when layer-lists are dirty.
3561 // It is somehow getting triggered during style update.
3562 if (m_stackingNode->zOrderListsDirty() || m_stackingNode->normalFlowListDirty())
3565 // FIXME: We currently only check the immediate renderer,
3566 // which will miss many cases.
3567 if (renderer()->backgroundIsKnownToBeOpaqueInRect(localRect))
3570 // We can't consult child layers if we clip, since they might cover
3571 // parts of the rect that are clipped out.
3572 if (renderer()->hasOverflowClip())
3575 return childBackgroundIsKnownToBeOpaqueInRect(localRect);
3578 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
3580 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren);
3581 while (RenderLayerStackingNode* child = revertseIterator.next()) {
3582 const RenderLayer* childLayer = child->layer();
3583 if (childLayer->hasCompositedLayerMapping())
3586 if (!childLayer->canUseConvertToLayerCoords())
3589 LayoutPoint childOffset;
3590 LayoutRect childLocalRect(localRect);
3591 childLayer->convertToLayerCoords(this, childOffset);
3592 childLocalRect.moveBy(-childOffset);
3594 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect))
3600 void RenderLayer::setParent(RenderLayer* parent)
3602 if (parent == m_parent)
3605 if (m_parent && !renderer()->documentBeingDestroyed())
3606 compositor()->layerWillBeRemoved(m_parent, this);
3610 if (m_parent && !renderer()->documentBeingDestroyed())
3611 compositor()->layerWasAdded(m_parent, this);
3614 bool RenderLayer::shouldBeSelfPaintingLayer() const
3616 return m_layerType == NormalLayer
3617 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
3618 || needsCompositedScrolling();
3621 void RenderLayer::updateSelfPaintingLayer()
3623 bool isSelfPaintingLayer = this->shouldBeSelfPaintingLayer();
3624 if (this->isSelfPaintingLayer() == isSelfPaintingLayer)
3627 m_isSelfPaintingLayer = isSelfPaintingLayer;
3630 if (isSelfPaintingLayer)
3631 parent()->setAncestorChainHasSelfPaintingLayerDescendant();
3633 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
3636 bool RenderLayer::hasNonEmptyChildRenderers() const
3638 // Some HTML can cause whitespace text nodes to have renderers, like:
3642 // so test for 0x0 RenderTexts here
3643 for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
3644 if (!child->hasLayer()) {
3645 if (child->isRenderInline() || !child->isBox())
3648 if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
3655 static bool hasBoxDecorations(const RenderStyle* style)
3657 return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
3660 bool RenderLayer::hasBoxDecorationsOrBackground() const
3662 return hasBoxDecorations(renderer()->style()) || renderer()->hasBackground();
3665 bool RenderLayer::hasVisibleBoxDecorations() const
3667 if (!hasVisibleContent())
3670 return hasBoxDecorationsOrBackground() || hasOverflowControls();
3673 bool RenderLayer::isVisuallyNonEmpty() const
3675 ASSERT(!m_visibleDescendantStatusDirty);
3677 if (hasVisibleContent() && hasNonEmptyChildRenderers())
3680 if (renderer()->isReplaced() || renderer()->hasMask())
3683 if (hasVisibleBoxDecorations())
3689 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
3691 ASSERT(!oldStyle || renderer()->style()->position() != oldStyle->position());
3693 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsolutePosition || oldStyle->position() == FixedPosition);
3694 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned();
3695 if (!wasOutOfFlowPositioned && !isOutOfFlowPositioned)
3698 // Even if the layer remains out-of-flow, a change to this property
3699 // will likely change its containing block. We must clear these bits
3700 // so that they can be set properly by the RenderLayerCompositor.
3701 for (RenderLayer* ancestor = parent(); ancestor; ancestor = ancestor->parent())
3702 ancestor->setHasUnclippedDescendant(false);
3704 // Ensures that we reset the above bits correctly.
3705 compositor()->setNeedsUpdateCompositingRequirementsState();
3707 if (wasOutOfFlowPositioned && isOutOfFlowPositioned)
3710 if (isOutOfFlowPositioned) {
3711 setAncestorChainHasOutOfFlowPositionedDescendant();
3712 compositor()->addOutOfFlowPositionedLayer(this);
3714 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
3715 compositor()->removeOutOfFlowPositionedLayer(this);
3717 // We need to reset the isUnclippedDescendant bit here because normally
3718 // the "unclipped-ness" property is only updated in
3719 // RenderLayerCompositor::updateCompositingRequirementsState(). However,
3720 // it is only updated for layers which are known to be out of flow.
3721 // Since this is no longer out of flow, we have to explicitly ensure
3722 // that it doesn't think it is unclipped.
3723 setIsUnclippedDescendant(false);
3727 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
3730 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter();
3733 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
3736 return oldStyle && (oldStyle->clip() != newStyle->clip() || oldStyle->hasClip() != newStyle->hasClip());
3739 inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
3742 return !hasCompositedLayerMapping()
3744 && (oldStyle->overflowX() != newStyle->overflowX())
3745 && m_stackingNode->ancestorStackingContainerNode()
3746 && m_stackingNode->ancestorStackingContainerNode()->layer()->hasCompositingDescendant();
3749 inline bool RenderLayer::needsCompositingLayersRebuiltForFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle, bool didPaintWithFilters) const
3751 if (!hasOrHadFilters(oldStyle, newStyle))
3754 if (hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitFilter)) {
3756 // When the compositor is performing the filter animation, we shouldn't touch the compositing layers.
3757 // All of the layers above us should have been promoted to compositing layers already.
3761 FilterOutsets newOutsets = newStyle->filterOutsets();
3762 if (oldStyle && (oldStyle->filterOutsets() != newOutsets)) {
3763 // When filter outsets change, we need to:
3764 // (1) Recompute the overlap map to promote the correct layers to composited layers.
3765 // (2) Update the composited layer bounds (and child GraphicsLayer positions) on platforms
3766 // whose compositors can't compute their own filter outsets.
3770 #if HAVE(COMPOSITOR_FILTER_OUTSETS)
3771 if ((didPaintWithFilters != paintsWithFilters()) && !newOutsets.isZero()) {
3772 // When the layer used to paint filters in software and now paints filters in the
3773 // compositor, the compositing layer bounds need to change from including filter outsets to
3774 // excluding filter outsets, on platforms whose compositors compute their own outsets.
3775 // Similarly for the reverse change from compositor-painted to software-painted filters.
3783 inline bool RenderLayer::needsCompositingLayersRebuiltForBlending(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
3786 if (!hasCompositedLayerMapping())
3788 return (shouldIsolateCompositedDescendants() && !stackingNode()->isStackingContext())
3789 || (oldStyle && (oldStyle->hasBlendMode() != newStyle->hasBlendMode()));
3792 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
3794 if (!hasOrHadFilters(oldStyle, newStyle))
3797 updateOrRemoveFilterClients();
3798 // During an accelerated animation, both WebKit and the compositor animate properties.
3799 // However, WebKit shouldn't ask the compositor to update its filters if the compositor is performing the animation.
3800 if (hasCompositedLayerMapping() && !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitFilter))
3801 compositedLayerMapping()->updateFilters(renderer()->style());
3802 updateOrRemoveFilterEffectRenderer();
3805 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
3807 m_stackingNode->updateIsNormalFlowOnly();
3809 if (m_scrollableArea)
3810 m_scrollableArea->updateAfterStyleChange(oldStyle);
3811 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
3813 if (!oldStyle || oldStyle->visibility() != renderer()->style()->visibility()) {
3814 ASSERT(!oldStyle || diff >= StyleDifferenceRepaint);
3815 compositor()->setNeedsUpdateCompositingRequirementsState();
3818 // Overlay scrollbars can make this layer self-painting so we need
3819 // to recompute the bit once scrollbars have been updated.
3820 updateSelfPaintingLayer();
3822 if (!oldStyle || renderer()->style()->position() != oldStyle->position()) {
3823 ASSERT(!oldStyle || diff >= StyleDifferenceLayout);
3824 updateOutOfFlowPositioned(oldStyle);
3827 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
3828 ASSERT(!oldStyle || diff >= StyleDifferenceLayout);
3829 updateReflectionInfo(oldStyle);
3832 if (RuntimeEnabledFeatures::cssCompositingEnabled())
3833 m_blendInfo.updateBlendMode();
3835 updateDescendantDependentFlags();
3837 if (!oldStyle || !renderer()->style()->transformDataEquivalent(oldStyle))
3840 bool didPaintWithFilters = false;
3843 // https://code.google.com/p/chromium/issues/detail?id=343759
3844 DisableCompositingQueryAsserts disabler;
3845 if (paintsWithFilters())
3846 didPaintWithFilters = true;
3847 updateFilters(oldStyle, renderer()->style());
3850 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
3851 // https://code.google.com/p/chromium/issues/detail?id=343756
3852 DisableCompositingQueryAsserts disabler;
3854 const RenderStyle* newStyle = renderer()->style();
3856 compositor()->updateLayerCompositingState(this);
3857 // FIXME: this compositing logic should be pushed into the compositing code, not here.
3858 if (needsCompositingLayersRebuiltForClip(oldStyle, newStyle)
3859 || needsCompositingLayersRebuiltForOverflow(oldStyle, newStyle)
3860 || needsCompositingLayersRebuiltForFilters(oldStyle, newStyle, didPaintWithFilters)
3861 || needsCompositingLayersRebuiltForBlending(oldStyle, newStyle)) {
3862 compositor()->setCompositingLayersNeedRebuild();
3866 bool RenderLayer::scrollsOverflow() const
3868 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
3869 return scrollableArea->scrollsOverflow();
3874 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
3876 const FilterOperations& filters = style->filter();
3877 if (filters.hasReferenceFilter()) {
3878 for (size_t i = 0; i < filters.size(); ++i) {
3879 FilterOperation* filterOperation = filters.operations().at(i).get();
3880 if (filterOperation->type() != FilterOperation::REFERENCE)
3882 ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
3883 // FIXME: Cache the ReferenceFilter if it didn't change.
3884 RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create();
3885 float zoom = style->effectiveZoom() * WebCore::deviceScaleFactor(renderer()->frame());
3886 referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom));
3887 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
3888 referenceOperation));
3889 referenceOperation->setFilter(referenceFilter.release());
3896 void RenderLayer::updateOrRemoveFilterClients()
3899 removeFilterInfoIfNeeded();
3903 if (renderer()->style()->filter().hasReferenceFilter())
3904 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter());
3905 else if (hasFilterInfo())
3906 filterInfo()->removeReferenceFilterClients();
3909 void RenderLayer::updateOrRemoveFilterEffectRenderer()
3911 // FilterEffectRenderer is only used to render the filters in software mode,
3912 // so we always need to run updateOrRemoveFilterEffectRenderer after the composited
3913 // mode might have changed for this layer.
3914 if (!paintsWithFilters()) {
3915 // Don't delete the whole filter info here, because we might use it
3916 // for loading CSS shader files.
3917 if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
3918 filterInfo->setRenderer(0);
3923 RenderLayerFilterInfo* filterInfo = ensureFilterInfo();
3924 if (!filterInfo->renderer()) {
3925 RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
3926 filterRenderer->setIsAccelerated(renderer()->frame()->settings()->acceleratedFiltersEnabled());
3927 filterInfo->setRenderer(filterRenderer.release());
3929 // We can optimize away code paths in other places if we know that there are no software filters.
3930 renderer()->document().view()->setHasSoftwareFilters(true);
3933 // If the filter fails to build, remove it from the layer. It will still attempt to
3934 // go through regular processing (e.g. compositing), but never apply anything.
3935 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
3936 filterInfo->setRenderer(0);
3939 void RenderLayer::filterNeedsRepaint()
3942 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle());
3943 // It's possible for scheduleLayerUpdate to schedule a style recalc, which
3944 // is a problem because this function can be called while performing layout.
3945 // Presumably this represents an illegal data flow of layout or compositing
3946 // information into the style system.
3947 toElement(renderer()->node())->scheduleLayerUpdate();
3950 if (renderer()->view()) {
3951 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && renderer()->frameView()->isInPerformLayout())
3952 renderer()->setShouldDoFullRepaintAfterLayout(true);
3954 renderer()->repaint();
3958 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const
3960 computeSelfHitTestRects(rects);
3961 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
3962 child->addLayerHitTestRects(rects);
3965 void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const
3967 if (!size().isEmpty()) {
3968 Vector<LayoutRect> rect;
3970 if (renderBox() && renderBox()->scrollsOverflow()) {
3971 // For scrolling layers, rects are taken to be in the space of the contents.
3972 // We need to include the bounding box of the layer in the space of its parent
3973 // (eg. for border / scroll bars) and if it's composited then the entire contents
3974 // as well as they may be on another composited layer. Skip reporting contents
3975 // for non-composited layers as they'll get projected to the same layer as the
3977 if (compositingState() != NotComposited)
3978 rect.append(m_scrollableArea->overflowRect());
3980 rects.set(this, rect);
3981 if (const RenderLayer* parentLayer = parent()) {
3982 LayerHitTestRects::iterator iter = rects.find(parentLayer);
3983 if (iter == rects.end()) {
3984 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(boundingBox(parentLayer));
3986 iter->value.append(boundingBox(parentLayer));
3990 rect.append(localBoundingBox());
3991 rects.set(this, rect);
3996 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
3997 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
3999 } // namespace WebCore
4002 void showLayerTree(const WebCore::RenderLayer* layer)
4007 if (WebCore::Frame* frame = layer->renderer()->frame()) {
4008 WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState);
4009 fprintf(stderr, "%s\n", output.utf8().data());
4013 void showLayerTree(const WebCore::RenderObject* renderer)
4017 showLayerTree(renderer->enclosingLayer());