mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
There is a slight change in behavior in FrameSelection::revealSelection. If you have a non-collapsed selection, then we'll center the start of the selection instead of the whole selection in some cases. There's a ton of callers of this code, so it's hard to be sure if any of this actually changes behavior for sky. In manual testing, I couldn't find any scenarios where there was a difference. Almost universally, when we call revealSelection, we have a CaretSelection. The only case I could think of where we have a RangeSelection is when modifying an off-screen selection (e.g. shift+right), but in that case we pass the RevealExtent option, so this patch doesn't change behavior there. Removing that caller makes all the rest of this rect computing code into dead code. R=abarth@chromium.org Review URL: https://codereview.chromium.org/847303003
555 lines
27 KiB
C++
555 lines
27 KiB
C++
/*
|
|
* Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved.
|
|
* Copyright (C) 2013 Intel Corporation. All rights reserved.
|
|
*
|
|
* Portions are Copyright (C) 1998 Netscape Communications Corporation.
|
|
*
|
|
* Other contributors:
|
|
* Robert O'Callahan <roc+@cs.cmu.edu>
|
|
* David Baron <dbaron@fas.harvard.edu>
|
|
* Christian Biesinger <cbiesinger@web.de>
|
|
* Randall Jesup <rjesup@wgate.com>
|
|
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
|
* Josh Soref <timeless@mac.com>
|
|
* Boris Zbarsky <bzbarsky@mit.edu>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms
|
|
* of either the Mozilla Public License Version 1.1, found at
|
|
* http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
|
|
* License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
|
|
* (the "GPL"), in which case the provisions of the MPL or the GPL are
|
|
* applicable instead of those above. If you wish to allow use of your
|
|
* version of this file only under the terms of one of those two
|
|
* licenses (the MPL or the GPL) and not to allow others to use your
|
|
* version of this file under the LGPL, indicate your decision by
|
|
* deletingthe provisions above and replace them with the notice and
|
|
* other provisions required by the MPL or the GPL, as the case may be.
|
|
* If you do not delete the provisions above, a recipient may use your
|
|
* version of this file under any of the LGPL, the MPL or the GPL.
|
|
*/
|
|
|
|
#ifndef SKY_ENGINE_CORE_RENDERING_RENDERLAYER_H_
|
|
#define SKY_ENGINE_CORE_RENDERING_RENDERLAYER_H_
|
|
|
|
#include "sky/engine/core/rendering/LayerPaintingInfo.h"
|
|
#include "sky/engine/core/rendering/RenderBox.h"
|
|
#include "sky/engine/core/rendering/RenderLayerClipper.h"
|
|
#include "sky/engine/core/rendering/RenderLayerFilterInfo.h"
|
|
#include "sky/engine/core/rendering/RenderLayerScrollableArea.h"
|
|
#include "sky/engine/core/rendering/RenderLayerStackingNode.h"
|
|
#include "sky/engine/core/rendering/RenderLayerStackingNodeIterator.h"
|
|
#include "sky/engine/public/platform/WebBlendMode.h"
|
|
#include "sky/engine/wtf/OwnPtr.h"
|
|
|
|
namespace blink {
|
|
|
|
class FilterEffectRenderer;
|
|
class FilterOperations;
|
|
class HitTestRequest;
|
|
class HitTestResult;
|
|
class HitTestingTransformState;
|
|
class RenderStyle;
|
|
class TransformationMatrix;
|
|
|
|
enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
|
|
enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
|
|
|
|
class RenderLayer {
|
|
WTF_MAKE_NONCOPYABLE(RenderLayer);
|
|
public:
|
|
RenderLayer(RenderLayerModelObject*, LayerType);
|
|
~RenderLayer();
|
|
|
|
String debugName() const;
|
|
|
|
RenderLayerModelObject* renderer() const { return m_renderer; }
|
|
RenderBox* renderBox() const { return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0; }
|
|
RenderLayer* parent() const { return m_parent; }
|
|
RenderLayer* previousSibling() const { return m_previous; }
|
|
RenderLayer* nextSibling() const { return m_next; }
|
|
RenderLayer* firstChild() const { return m_first; }
|
|
RenderLayer* lastChild() const { return m_last; }
|
|
|
|
const RenderLayer* compositingContainer() const;
|
|
|
|
void addChild(RenderLayer* newChild, RenderLayer* beforeChild = 0);
|
|
RenderLayer* removeChild(RenderLayer*);
|
|
|
|
void removeOnlyThisLayer();
|
|
void insertOnlyThisLayer();
|
|
|
|
void styleChanged(StyleDifference, const RenderStyle* oldStyle);
|
|
|
|
// FIXME: Many people call this function while it has out-of-date information.
|
|
bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
|
|
|
|
void setLayerType(LayerType layerType) { m_layerType = layerType; }
|
|
|
|
bool isTransparent() const { return renderer()->isTransparent() || renderer()->hasMask(); }
|
|
RenderLayer* transparentPaintingAncestor();
|
|
void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation);
|
|
|
|
const RenderLayer* root() const
|
|
{
|
|
const RenderLayer* curr = this;
|
|
while (curr->parent())
|
|
curr = curr->parent();
|
|
return curr;
|
|
}
|
|
|
|
LayoutPoint location() const;
|
|
IntSize size() const;
|
|
|
|
LayoutRect rect() const { return LayoutRect(location(), size()); }
|
|
|
|
bool isRootLayer() const { return m_isRootLayer; }
|
|
|
|
void updateLayerPositionsAfterLayout();
|
|
|
|
void updateTransformationMatrix();
|
|
RenderLayer* renderingContextRoot();
|
|
|
|
// Our current relative position offset.
|
|
const LayoutSize offsetForInFlowPosition() const;
|
|
|
|
RenderLayerStackingNode* stackingNode() { return m_stackingNode.get(); }
|
|
const RenderLayerStackingNode* stackingNode() const { return m_stackingNode.get(); }
|
|
|
|
bool hasBoxDecorationsOrBackground() const;
|
|
bool hasVisibleBoxDecorations() const;
|
|
// Returns true if this layer has visible content (ignoring any child layers).
|
|
bool isVisuallyNonEmpty() const;
|
|
// True if this layer container renderers that paint.
|
|
bool hasNonEmptyChildRenderers() const;
|
|
|
|
bool usedTransparency() const { return m_usedTransparency; }
|
|
|
|
// Gets the nearest enclosing positioned ancestor layer (also includes
|
|
// the <html> layer and the root layer).
|
|
RenderLayer* enclosingPositionedAncestor() const;
|
|
|
|
RenderLayer* enclosingOverflowClipLayer(IncludeSelfOrNot = IncludeSelf) const;
|
|
|
|
RenderLayer* enclosingFilterLayer(IncludeSelfOrNot = IncludeSelf) const;
|
|
bool hasAncestorWithFilterOutsets() const;
|
|
|
|
bool canUseConvertToLayerCoords() const
|
|
{
|
|
return !renderer()->hasTransform();
|
|
}
|
|
|
|
void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint&) const;
|
|
void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect&) const;
|
|
|
|
// The two main functions that use the layer system. The paint method
|
|
// paints the layers that intersect the damage rect from back to
|
|
// front. The hitTest method looks for mouse events by walking
|
|
// layers that intersect the point from front to back.
|
|
// paint() assumes that the caller will clip to the bounds of damageRect if necessary.
|
|
void paint(GraphicsContext*, const LayoutRect& damageRect, RenderObject* paintingRoot = 0);
|
|
bool hitTest(const HitTestRequest&, HitTestResult&);
|
|
bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
|
|
void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, RenderObject* paintingRoot = 0);
|
|
|
|
// Pass offsetFromRoot if known.
|
|
bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const;
|
|
|
|
// Bounding box relative to some ancestor layer. Pass offsetFromRoot if known.
|
|
LayoutRect physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0) const;
|
|
LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const;
|
|
|
|
// FIXME: This function is inconsistent as to whether the returned rect has been flipped for writing mode.
|
|
LayoutRect boundingBoxForCompositingOverlapTest() const { return overlapBoundsIncludeChildren() ? boundingBoxForCompositing() : logicalBoundingBox(); }
|
|
|
|
// If true, this layer's children are included in its bounds for overlap testing.
|
|
// We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around.
|
|
bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer()->style()->filter().hasFilterThatMovesPixels(); }
|
|
|
|
enum CalculateBoundsOptions {
|
|
ApplyBoundsChickenEggHacks,
|
|
DoNotApplyBoundsChickenEggHacks,
|
|
};
|
|
LayoutRect boundingBoxForCompositing(const RenderLayer* ancestorLayer = 0, CalculateBoundsOptions = DoNotApplyBoundsChickenEggHacks) const;
|
|
|
|
LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; }
|
|
LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; }
|
|
|
|
void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; }
|
|
void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; }
|
|
|
|
LayoutSize subpixelAccumulation() const;
|
|
void setSubpixelAccumulation(const LayoutSize&);
|
|
|
|
bool hasTransform() const { return renderer()->hasTransform(); }
|
|
// Note that this transform has the transform-origin baked in.
|
|
TransformationMatrix* transform() const { return m_transform.get(); }
|
|
// currentTransform computes a transform which takes accelerated animations into account. The
|
|
// resulting transform has transform-origin baked in. If the layer does not have a transform,
|
|
// returns the identity matrix.
|
|
TransformationMatrix currentTransform(RenderStyle::ApplyTransformOrigin = RenderStyle::IncludeTransformOrigin) const;
|
|
TransformationMatrix renderableTransform() const;
|
|
|
|
// Get the perspective transform, which is applied to transformed sublayers.
|
|
// Returns true if the layer has a -webkit-perspective.
|
|
// Note that this transform has the perspective-origin baked in.
|
|
TransformationMatrix perspectiveTransform() const;
|
|
FloatPoint perspectiveOrigin() const;
|
|
bool preserves3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
|
|
bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
|
|
|
|
// FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
|
|
bool shouldPreserve3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
|
|
|
|
void filterNeedsPaintInvalidation();
|
|
bool hasFilter() const { return renderer()->hasFilter(); }
|
|
|
|
void* operator new(size_t);
|
|
// Only safe to call from RenderLayerModelObject::destroyLayer()
|
|
void operator delete(void*);
|
|
|
|
bool needsCompositedScrolling() const { return m_scrollableArea && m_scrollableArea->needsCompositedScrolling(); }
|
|
|
|
// Computes the position of the given render object in the space of |paintInvalidationContainer|.
|
|
// FIXME: invert the logic to have paint invalidation containers take care of painting objects into them, rather than the reverse.
|
|
// This will allow us to clean up this static method messiness.
|
|
static LayoutPoint positionFromPaintInvalidationContainer(const RenderObject*, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* = 0);
|
|
|
|
bool paintsWithTransform() const;
|
|
|
|
// Returns true if background phase is painted opaque in the given rect.
|
|
// The query rect is given in local coordinates.
|
|
bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const;
|
|
|
|
bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; }
|
|
void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; }
|
|
|
|
FilterOperations computeFilterOperations(const RenderStyle*);
|
|
bool paintsWithFilters() const;
|
|
bool requiresFullLayerImageForFilters() const;
|
|
FilterEffectRenderer* filterRenderer() const
|
|
{
|
|
RenderLayerFilterInfo* filterInfo = this->filterInfo();
|
|
return filterInfo ? filterInfo->renderer() : 0;
|
|
}
|
|
|
|
RenderLayerFilterInfo* filterInfo() const { return hasFilterInfo() ? RenderLayerFilterInfo::filterInfoForRenderLayer(this) : 0; }
|
|
RenderLayerFilterInfo* ensureFilterInfo() { return RenderLayerFilterInfo::createFilterInfoForRenderLayerIfNeeded(this); }
|
|
void removeFilterInfoIfNeeded()
|
|
{
|
|
if (hasFilterInfo())
|
|
RenderLayerFilterInfo::removeFilterInfoForRenderLayer(this);
|
|
}
|
|
|
|
bool hasFilterInfo() const { return m_hasFilterInfo; }
|
|
void setHasFilterInfo(bool hasFilterInfo) { m_hasFilterInfo = hasFilterInfo; }
|
|
|
|
void updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle);
|
|
|
|
Node* enclosingElement() const;
|
|
|
|
bool scrollsWithRespectTo(const RenderLayer*) const;
|
|
|
|
// FIXME: This should probably return a ScrollableArea but a lot of internal methods are mistakenly exposed.
|
|
RenderLayerScrollableArea* scrollableArea() const { return m_scrollableArea.get(); }
|
|
RenderLayerClipper& clipper() { return m_clipper; }
|
|
const RenderLayerClipper& clipper() const { return m_clipper; }
|
|
|
|
inline bool isPositionedContainer() const
|
|
{
|
|
// FIXME: This is not in sync with containingBlock.
|
|
RenderLayerModelObject* layerRenderer = renderer();
|
|
return isRootLayer() || layerRenderer->isPositioned() || hasTransform();
|
|
}
|
|
|
|
bool scrollsOverflow() const;
|
|
|
|
class AncestorDependentCompositingInputs {
|
|
public:
|
|
AncestorDependentCompositingInputs()
|
|
: opacityAncestor(0)
|
|
, transformAncestor(0)
|
|
, filterAncestor(0)
|
|
, clippingContainer(0)
|
|
, ancestorScrollingLayer(0)
|
|
, scrollParent(0)
|
|
, clipParent(0)
|
|
, isUnclippedDescendant(false)
|
|
, hasAncestorWithClipPath(false)
|
|
{ }
|
|
|
|
IntRect clippedAbsoluteBoundingBox;
|
|
const RenderLayer* opacityAncestor;
|
|
const RenderLayer* transformAncestor;
|
|
const RenderLayer* filterAncestor;
|
|
const RenderObject* clippingContainer;
|
|
const RenderLayer* ancestorScrollingLayer;
|
|
|
|
// A scroll parent is a compositor concept. It's only needed in blink
|
|
// because we need to use it as a promotion trigger. A layer has a
|
|
// scroll parent if neither its compositor scrolling ancestor, nor any
|
|
// other layer scrolled by this ancestor, is a stacking ancestor of this
|
|
// layer. Layers with scroll parents must be scrolled with the main
|
|
// scrolling layer by the compositor.
|
|
const RenderLayer* scrollParent;
|
|
|
|
// A clip parent is another compositor concept that has leaked into
|
|
// blink so that it may be used as a promotion trigger. Layers with clip
|
|
// parents escape the clip of a stacking tree ancestor. The compositor
|
|
// needs to know about clip parents in order to circumvent its normal
|
|
// clipping logic.
|
|
const RenderLayer* clipParent;
|
|
|
|
// The "is unclipped descendant" concept is now only being used for one
|
|
// purpose: when traversing the RenderLayers in stacking order, we check
|
|
// if we scroll wrt to these unclipped descendants. We do this to
|
|
// proactively promote in the same way that we do for animated layers.
|
|
// Since we have no idea where scrolled content will scroll to, we just
|
|
// assume that it can overlap the unclipped thing at some point, so we
|
|
// promote. But this is unfortunate. We should be able to inflate the
|
|
// bounds of scrolling content for overlap the same way we're doing for
|
|
// animation and only promote what's necessary. Once we're doing that,
|
|
// we won't need to use the "unclipped" concept for promotion any
|
|
// longer.
|
|
unsigned isUnclippedDescendant : 1;
|
|
unsigned hasAncestorWithClipPath : 1;
|
|
};
|
|
|
|
class DescendantDependentCompositingInputs {
|
|
public:
|
|
DescendantDependentCompositingInputs()
|
|
: hasDescendantWithClipPath(false)
|
|
|
|
{ }
|
|
|
|
unsigned hasDescendantWithClipPath : 1;
|
|
};
|
|
|
|
bool childNeedsCompositingInputsUpdate() const { return m_childNeedsCompositingInputsUpdate; }
|
|
bool needsCompositingInputsUpdate() const
|
|
{
|
|
// While we're updating the compositing inputs, these values may differ.
|
|
// We should never be asking for this value when that is the case.
|
|
ASSERT(m_needsDescendantDependentCompositingInputsUpdate == m_needsAncestorDependentCompositingInputsUpdate);
|
|
return m_needsDescendantDependentCompositingInputsUpdate;
|
|
}
|
|
|
|
void updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs&);
|
|
void updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs&);
|
|
|
|
const AncestorDependentCompositingInputs& ancestorDependentCompositingInputs() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_ancestorDependentCompositingInputs; }
|
|
const DescendantDependentCompositingInputs& descendantDependentCompositingInputs() const { ASSERT(!m_needsDescendantDependentCompositingInputsUpdate); return m_descendantDependentCompositingInputs; }
|
|
|
|
IntRect clippedAbsoluteBoundingBox() const { return ancestorDependentCompositingInputs().clippedAbsoluteBoundingBox; }
|
|
const RenderLayer* opacityAncestor() const { return ancestorDependentCompositingInputs().opacityAncestor; }
|
|
const RenderLayer* transformAncestor() const { return ancestorDependentCompositingInputs().transformAncestor; }
|
|
const RenderLayer* filterAncestor() const { return ancestorDependentCompositingInputs().filterAncestor; }
|
|
const RenderObject* clippingContainer() const { return ancestorDependentCompositingInputs().clippingContainer; }
|
|
const RenderLayer* ancestorScrollingLayer() const { return ancestorDependentCompositingInputs().ancestorScrollingLayer; }
|
|
RenderLayer* scrollParent() const { return const_cast<RenderLayer*>(ancestorDependentCompositingInputs().scrollParent); }
|
|
RenderLayer* clipParent() const { return const_cast<RenderLayer*>(ancestorDependentCompositingInputs().clipParent); }
|
|
bool isUnclippedDescendant() const { return ancestorDependentCompositingInputs().isUnclippedDescendant; }
|
|
bool hasAncestorWithClipPath() const { return ancestorDependentCompositingInputs().hasAncestorWithClipPath; }
|
|
bool hasDescendantWithClipPath() const { return descendantDependentCompositingInputs().hasDescendantWithClipPath; }
|
|
|
|
bool lostGroupedMapping() const { return m_lostGroupedMapping; }
|
|
void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; }
|
|
|
|
bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
|
|
void setHasCompositingDescendant(bool);
|
|
|
|
void updateOrRemoveFilterEffectRenderer();
|
|
|
|
void updateSelfPaintingLayer();
|
|
|
|
RenderLayer* enclosingTransformedAncestor() const;
|
|
LayoutPoint computeOffsetFromTransformedAncestor() const;
|
|
|
|
void didUpdateNeedsCompositedScrolling();
|
|
|
|
private:
|
|
// TODO(ojan): Get rid of this. These are basically layer-tree-only paint phases.
|
|
enum PaintLayerFlags {
|
|
PaintContent,
|
|
PaintOverlayScrollbars,
|
|
};
|
|
|
|
// Bounding box in the coordinates of this layer.
|
|
LayoutRect logicalBoundingBox() const;
|
|
|
|
bool hasOverflowControls() const;
|
|
|
|
void setAncestorChainHasSelfPaintingLayerDescendant();
|
|
void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
|
|
|
|
void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
|
|
void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
|
|
|
|
void setNextSibling(RenderLayer* next) { m_next = next; }
|
|
void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
|
|
void setFirstChild(RenderLayer* first) { m_first = first; }
|
|
void setLastChild(RenderLayer* last) { m_last = last; }
|
|
|
|
void updateHasSelfPaintingLayerDescendant() const;
|
|
|
|
bool hasSelfPaintingLayerDescendant() const
|
|
{
|
|
if (m_hasSelfPaintingLayerDescendantDirty)
|
|
updateHasSelfPaintingLayerDescendant();
|
|
ASSERT(!m_hasSelfPaintingLayerDescendantDirty);
|
|
return m_hasSelfPaintingLayerDescendant;
|
|
}
|
|
|
|
LayoutPoint renderBoxLocation() const { return renderer()->isBox() ? toRenderBox(renderer())->location() : LayoutPoint(); }
|
|
|
|
// paintLayer() assumes that the caller will clip to the bounds of the painting dirty if necessary.
|
|
void paintLayer(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
|
|
|
|
// paintLayerContents() assumes that the caller will clip to the bounds of the painting dirty rect if necessary.
|
|
void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
|
|
|
|
void paintLayerByApplyingTransform(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& translationOffset = LayoutPoint());
|
|
|
|
void paintChildren(unsigned childrenToVisit, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
|
|
|
|
void paintBackground(GraphicsContext*, GraphicsContext* transparencyLayerContext,
|
|
const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer,
|
|
LayoutPoint& layerLocation, ClipRect& layerBackgroundRect);
|
|
void paintForeground(GraphicsContext*, GraphicsContext* transparencyLayerContext,
|
|
const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer,
|
|
LayoutPoint& layerLocation, ClipRect& layerForegroundRect);
|
|
void paintForegroundWithPhase(PaintPhase, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer,
|
|
LayoutPoint& layerLocation, ClipRect& layerForegroundRect);
|
|
void paintOutline(GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer,
|
|
LayoutPoint& layerLocation, ClipRect& layerOutlineRect);
|
|
void paintOverflowControls(GraphicsContext*, const LayerPaintingInfo&,
|
|
LayoutPoint& layerLocation, ClipRect& layerBackgroundRect);
|
|
void paintMask(GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer,
|
|
LayoutPoint& layerLocation, ClipRect& layerBackgroundRect);
|
|
|
|
RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
|
|
const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform,
|
|
const HitTestingTransformState* transformState = 0, double* zOffset = 0);
|
|
RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
|
|
const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = 0, double* zOffset = 0,
|
|
const LayoutPoint& translationOffset = LayoutPoint());
|
|
RenderLayer* hitTestChildren(ChildrenIteration, RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&,
|
|
const LayoutRect& hitTestRect, const HitTestLocation&,
|
|
const HitTestingTransformState* transformState, double* zOffsetForDescendants, double* zOffset,
|
|
const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants);
|
|
|
|
PassRefPtr<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
|
|
const LayoutRect& hitTestRect, const HitTestLocation&,
|
|
const HitTestingTransformState* containerTransformState,
|
|
const LayoutPoint& translationOffset = LayoutPoint()) const;
|
|
|
|
bool hitTestContents(const HitTestRequest&, HitTestResult&, const LayoutRect& layerBounds, const HitTestLocation&, HitTestFilter) const;
|
|
|
|
bool childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const;
|
|
|
|
bool shouldBeSelfPaintingLayer() const;
|
|
|
|
// FIXME: We should only create the stacking node if needed.
|
|
bool requiresStackingNode() const { return true; }
|
|
void updateStackingNode();
|
|
|
|
// FIXME: We could lazily allocate our ScrollableArea based on style properties ('overflow', ...)
|
|
// but for now, we are always allocating it for RenderBox as it's safer.
|
|
bool requiresScrollableArea() const { return renderBox(); }
|
|
void updateScrollableArea();
|
|
|
|
void updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle);
|
|
|
|
void dirty3DTransformedDescendantStatus();
|
|
// Both updates the status, and returns true if descendants of this have 3d.
|
|
bool update3DTransformedDescendantStatus();
|
|
|
|
void updateOrRemoveFilterClients();
|
|
|
|
LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation);
|
|
|
|
LayerType m_layerType;
|
|
|
|
// Self-painting layer is an optimization where we avoid the heavy RenderLayer painting
|
|
// machinery for a RenderLayer allocated only to handle the overflow clip case.
|
|
// FIXME(crbug.com/332791): Self-painting layer should be merged into the overflow-only concept.
|
|
unsigned m_isSelfPaintingLayer : 1;
|
|
|
|
// If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
|
|
// significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells).
|
|
mutable unsigned m_hasSelfPaintingLayerDescendant : 1;
|
|
mutable unsigned m_hasSelfPaintingLayerDescendantDirty : 1;
|
|
|
|
const unsigned m_isRootLayer : 1;
|
|
|
|
unsigned m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
|
|
// we ended up painting this layer or any descendants (and therefore need to
|
|
// blend).
|
|
|
|
unsigned m_3DTransformedDescendantStatusDirty : 1;
|
|
// Set on a stacking context layer that has 3D descendants anywhere
|
|
// in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
|
|
unsigned m_has3DTransformedDescendant : 1;
|
|
|
|
unsigned m_containsDirtyOverlayScrollbars : 1;
|
|
|
|
unsigned m_hasFilterInfo : 1;
|
|
unsigned m_needsAncestorDependentCompositingInputsUpdate : 1;
|
|
unsigned m_needsDescendantDependentCompositingInputsUpdate : 1;
|
|
unsigned m_childNeedsCompositingInputsUpdate : 1;
|
|
|
|
// Used only while determining what layers should be composited. Applies to the tree of z-order lists.
|
|
unsigned m_hasCompositingDescendant : 1;
|
|
|
|
// True if this render layer just lost its grouped mapping due to the CompositedLayerMapping being destroyed,
|
|
// and we don't yet know to what graphics layer this RenderLayer will be assigned.
|
|
unsigned m_lostGroupedMapping : 1;
|
|
|
|
RenderLayerModelObject* m_renderer;
|
|
|
|
RenderLayer* m_parent;
|
|
RenderLayer* m_previous;
|
|
RenderLayer* m_next;
|
|
RenderLayer* m_first;
|
|
RenderLayer* m_last;
|
|
|
|
// Cached normal flow values for absolute positioned elements with static left/top values.
|
|
LayoutUnit m_staticInlinePosition;
|
|
LayoutUnit m_staticBlockPosition;
|
|
|
|
OwnPtr<TransformationMatrix> m_transform;
|
|
|
|
DescendantDependentCompositingInputs m_descendantDependentCompositingInputs;
|
|
AncestorDependentCompositingInputs m_ancestorDependentCompositingInputs;
|
|
|
|
OwnPtr<RenderLayerScrollableArea> m_scrollableArea;
|
|
|
|
RenderLayerClipper m_clipper; // FIXME: Lazily allocate?
|
|
OwnPtr<RenderLayerStackingNode> m_stackingNode;
|
|
|
|
LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates.
|
|
};
|
|
|
|
} // namespace blink
|
|
|
|
#ifndef NDEBUG
|
|
// Outside the WebCore namespace for ease of invocation from gdb.
|
|
void showLayerTree(const blink::RenderLayer*);
|
|
void showLayerTree(const blink::RenderObject*);
|
|
#endif
|
|
|
|
#endif // SKY_ENGINE_CORE_RENDERING_RENDERLAYER_H_
|