| 1 | /* |
| 2 | * Copyright (C) 2003, 2009, 2012, 2015 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 | * |
| 6 | * Other contributors: |
| 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> |
| 14 | * |
| 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. |
| 19 | * |
| 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. |
| 24 | * |
| 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 |
| 28 | * |
| 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. |
| 42 | */ |
| 43 | |
| 44 | #pragma once |
| 45 | |
| 46 | #include "ClipRect.h" |
| 47 | #include "GraphicsLayer.h" |
| 48 | #include "LayerFragment.h" |
| 49 | #include "PaintFrequencyTracker.h" |
| 50 | #include "PaintInfo.h" |
| 51 | #include "RenderBox.h" |
| 52 | #include "RenderPtr.h" |
| 53 | #include "ScrollableArea.h" |
| 54 | #include <memory> |
| 55 | #include <wtf/WeakPtr.h> |
| 56 | |
| 57 | namespace WTF { |
| 58 | class TextStream; |
| 59 | } |
| 60 | |
| 61 | namespace WebCore { |
| 62 | |
| 63 | class CSSFilter; |
| 64 | class ClipRects; |
| 65 | class ClipRectsCache; |
| 66 | class EventRegionContext; |
| 67 | class HitTestRequest; |
| 68 | class HitTestResult; |
| 69 | class HitTestingTransformState; |
| 70 | class Region; |
| 71 | class RenderFragmentedFlow; |
| 72 | class RenderGeometryMap; |
| 73 | class RenderLayerBacking; |
| 74 | class RenderLayerCompositor; |
| 75 | class RenderLayerFilters; |
| 76 | class RenderMarquee; |
| 77 | class RenderReplica; |
| 78 | class RenderScrollbarPart; |
| 79 | class RenderStyle; |
| 80 | class RenderView; |
| 81 | class Scrollbar; |
| 82 | class TransformationMatrix; |
| 83 | |
| 84 | enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius }; |
| 85 | enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf }; |
| 86 | |
| 87 | enum RepaintStatus { |
| 88 | NeedsNormalRepaint, |
| 89 | NeedsFullRepaint, |
| 90 | NeedsFullRepaintForPositionedMovementLayout |
| 91 | }; |
| 92 | |
| 93 | enum ClipRectsType { |
| 94 | PaintingClipRects, // Relative to painting ancestor. Used for painting. |
| 95 | RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing. |
| 96 | AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing. |
| 97 | NumCachedClipRectsTypes, |
| 98 | AllClipRectTypes, |
| 99 | TemporaryClipRects |
| 100 | }; |
| 101 | |
| 102 | enum ShouldRespectOverflowClip { |
| 103 | IgnoreOverflowClip, |
| 104 | RespectOverflowClip |
| 105 | }; |
| 106 | |
| 107 | enum ShouldApplyRootOffsetToFragments { |
| 108 | ApplyRootOffsetToFragments, |
| 109 | IgnoreRootOffsetForFragments |
| 110 | }; |
| 111 | |
| 112 | enum class RequestState { |
| 113 | Unknown, |
| 114 | DontCare, |
| 115 | False, |
| 116 | True, |
| 117 | Undetermined |
| 118 | }; |
| 119 | |
| 120 | enum class IndirectCompositingReason { |
| 121 | None, |
| 122 | Stacking, |
| 123 | OverflowScrollPositioning, |
| 124 | Overlap, |
| 125 | BackgroundLayer, |
| 126 | GraphicalEffect, // opacity, mask, filter, transform etc. |
| 127 | Perspective, |
| 128 | Preserve3D |
| 129 | }; |
| 130 | |
| 131 | struct ScrollRectToVisibleOptions { |
| 132 | SelectionRevealMode revealMode { SelectionRevealMode::Reveal }; |
| 133 | const ScrollAlignment& alignX { ScrollAlignment::alignCenterIfNeeded }; |
| 134 | const ScrollAlignment& alignY { ScrollAlignment::alignCenterIfNeeded }; |
| 135 | ShouldAllowCrossOriginScrolling shouldAllowCrossOriginScrolling { ShouldAllowCrossOriginScrolling::No }; |
| 136 | }; |
| 137 | |
| 138 | class RenderLayer final : public ScrollableArea { |
| 139 | WTF_MAKE_FAST_ALLOCATED; |
| 140 | public: |
| 141 | friend class RenderReplica; |
| 142 | friend class RenderLayerFilters; |
| 143 | |
| 144 | explicit RenderLayer(RenderLayerModelObject&); |
| 145 | virtual ~RenderLayer(); |
| 146 | |
| 147 | #if PLATFORM(IOS_FAMILY) |
| 148 | // Called before the renderer's widget (if any) has been nulled out. |
| 149 | void willBeDestroyed(); |
| 150 | #endif |
| 151 | String name() const; |
| 152 | |
| 153 | Page& page() const { return renderer().page(); } |
| 154 | RenderLayerModelObject& renderer() const { return m_renderer; } |
| 155 | RenderBox* renderBox() const { return is<RenderBox>(renderer()) ? &downcast<RenderBox>(renderer()) : nullptr; } |
| 156 | |
| 157 | RenderLayer* parent() const { return m_parent; } |
| 158 | RenderLayer* previousSibling() const { return m_previous; } |
| 159 | RenderLayer* nextSibling() const { return m_next; } |
| 160 | RenderLayer* firstChild() const { return m_first; } |
| 161 | RenderLayer* lastChild() const { return m_last; } |
| 162 | bool isDescendantOf(const RenderLayer&) const; |
| 163 | |
| 164 | // This does an ancestor tree walk. Avoid it! |
| 165 | const RenderLayer* root() const |
| 166 | { |
| 167 | const RenderLayer* curr = this; |
| 168 | while (curr->parent()) |
| 169 | curr = curr->parent(); |
| 170 | return curr; |
| 171 | } |
| 172 | |
| 173 | void addChild(RenderLayer& newChild, RenderLayer* beforeChild = nullptr); |
| 174 | void removeChild(RenderLayer&); |
| 175 | |
| 176 | void insertOnlyThisLayer(); |
| 177 | void removeOnlyThisLayer(); |
| 178 | |
| 179 | bool isNormalFlowOnly() const { return m_isNormalFlowOnly; } |
| 180 | |
| 181 | // isStackingContext is true for layers that we've determined should be stacking contexts for painting. |
| 182 | // Not all stacking contexts are CSS stacking contexts. |
| 183 | bool isStackingContext() const { return isCSSStackingContext() || m_isOpportunisticStackingContext; } |
| 184 | |
| 185 | // isCSSStackingContext is true for layers that are stacking contexts from a CSS perspective. |
| 186 | // isCSSStackingContext() => isStackingContext(). |
| 187 | // FIXME: m_forcedStackingContext should affect isStackingContext(), not isCSSStackingContext(), but doing so breaks media control mix-blend-mode. |
| 188 | bool isCSSStackingContext() const { return m_isCSSStackingContext || m_forcedStackingContext; } |
| 189 | |
| 190 | // Gets the enclosing stacking context for this layer, excluding this layer itself. |
| 191 | RenderLayer* stackingContext() const; |
| 192 | |
| 193 | // Gets the enclosing stacking container for this layer, possibly the layer |
| 194 | // itself, if it is a stacking container. |
| 195 | RenderLayer* enclosingStackingContext() { return isStackingContext() ? this : stackingContext(); } |
| 196 | |
| 197 | RenderLayer* paintOrderParent() const; |
| 198 | |
| 199 | void dirtyNormalFlowList(); |
| 200 | void dirtyZOrderLists(); |
| 201 | void dirtyStackingContextZOrderLists(); |
| 202 | |
| 203 | bool normalFlowListDirty() const { return m_normalFlowListDirty; } |
| 204 | bool zOrderListsDirty() const { return m_zOrderListsDirty; } |
| 205 | |
| 206 | #if !ASSERT_DISABLED |
| 207 | bool layerListMutationAllowed() const { return m_layerListMutationAllowed; } |
| 208 | void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; } |
| 209 | #endif |
| 210 | |
| 211 | private: |
| 212 | // These flags propagate in paint order (z-order tree). |
| 213 | enum class Compositing { |
| 214 | HasDescendantNeedingRequirementsTraversal = 1 << 0, // Need to do the overlap-testing tree walk because hierarchy or geometry changed. |
| 215 | HasDescendantNeedingBackingOrHierarchyTraversal = 1 << 1, // Need to update geometry, configuration and update the GraphicsLayer tree. |
| 216 | |
| 217 | // Things that trigger HasDescendantNeedingRequirementsTraversal |
| 218 | NeedsPaintOrderChildrenUpdate = 1 << 2, // The paint order children of this layer changed (gained/lost child, order change). |
| 219 | NeedsPostLayoutUpdate = 1 << 3, // Needs compositing to be re-evaluated after layout (it depends on geometry). |
| 220 | DescendantsNeedRequirementsTraversal = 1 << 4, // Something changed that forces computeCompositingRequirements to traverse all descendant layers. |
| 221 | SubsequentLayersNeedRequirementsTraversal = 1 << 5, // Something changed that forces computeCompositingRequirements to traverse all layers later in paint order. |
| 222 | |
| 223 | // Things that trigger HasDescendantNeedingBackingOrHierarchyTraversal |
| 224 | NeedsGeometryUpdate = 1 << 6, // This layer needs a geometry update. |
| 225 | NeedsConfigurationUpdate = 1 << 7, // This layer needs a configuration update (updating its internal compositing hierarchy). |
| 226 | NeedsScrollingTreeUpdate = 1 << 8, // Something changed that requires this layer's scrolling tree node to be updated. |
| 227 | NeedsLayerConnection = 1 << 9, // This layer needs hookup with its parents or children. |
| 228 | ChildrenNeedGeometryUpdate = 1 << 10, // This layer's composited children need a geometry update. |
| 229 | DescendantsNeedBackingAndHierarchyTraversal = 1 << 11, // Something changed that forces us to traverse all descendant layers in updateBackingAndHierarchy. |
| 230 | }; |
| 231 | |
| 232 | static constexpr OptionSet<Compositing> computeCompositingRequirementsFlags() |
| 233 | { |
| 234 | return { |
| 235 | Compositing::NeedsPaintOrderChildrenUpdate, |
| 236 | Compositing::NeedsPostLayoutUpdate, |
| 237 | Compositing::DescendantsNeedRequirementsTraversal, |
| 238 | Compositing::SubsequentLayersNeedRequirementsTraversal, |
| 239 | }; |
| 240 | } |
| 241 | |
| 242 | static constexpr OptionSet<Compositing> updateBackingOrHierarchyFlags() |
| 243 | { |
| 244 | return { |
| 245 | Compositing::NeedsLayerConnection, |
| 246 | Compositing::NeedsGeometryUpdate, |
| 247 | Compositing::NeedsConfigurationUpdate, |
| 248 | Compositing::NeedsScrollingTreeUpdate, |
| 249 | Compositing::ChildrenNeedGeometryUpdate, |
| 250 | Compositing::DescendantsNeedBackingAndHierarchyTraversal, |
| 251 | }; |
| 252 | } |
| 253 | |
| 254 | void setAncestorsHaveCompositingDirtyFlag(Compositing); |
| 255 | |
| 256 | public: |
| 257 | bool hasDescendantNeedingCompositingRequirementsTraversal() const { return m_compositingDirtyBits.contains(Compositing::HasDescendantNeedingRequirementsTraversal); } |
| 258 | bool hasDescendantNeedingUpdateBackingOrHierarchyTraversal() const { return m_compositingDirtyBits.contains(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal); } |
| 259 | |
| 260 | bool needsCompositingPaintOrderChildrenUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsPaintOrderChildrenUpdate); } |
| 261 | bool needsPostLayoutCompositingUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsPostLayoutUpdate); } |
| 262 | bool descendantsNeedCompositingRequirementsTraversal() const { return m_compositingDirtyBits.contains(Compositing::DescendantsNeedRequirementsTraversal); } |
| 263 | bool subsequentLayersNeedCompositingRequirementsTraversal() const { return m_compositingDirtyBits.contains(Compositing::SubsequentLayersNeedRequirementsTraversal); } |
| 264 | |
| 265 | bool needsCompositingLayerConnection() const { return m_compositingDirtyBits.contains(Compositing::NeedsLayerConnection); } |
| 266 | bool needsCompositingGeometryUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsGeometryUpdate); } |
| 267 | bool needsCompositingConfigurationUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsConfigurationUpdate); } |
| 268 | bool needsScrollingTreeUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsScrollingTreeUpdate); } |
| 269 | bool childrenNeedCompositingGeometryUpdate() const { return m_compositingDirtyBits.contains(Compositing::ChildrenNeedGeometryUpdate); } |
| 270 | bool descendantsNeedUpdateBackingAndHierarchyTraversal() const { return m_compositingDirtyBits.contains(Compositing::DescendantsNeedBackingAndHierarchyTraversal); } |
| 271 | |
| 272 | template<Compositing V> |
| 273 | void setRequirementsTraversalDirtyBit() |
| 274 | { |
| 275 | m_compositingDirtyBits.add(V); |
| 276 | setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingRequirementsTraversal); |
| 277 | } |
| 278 | |
| 279 | void setNeedsCompositingPaintOrderChildrenUpdate() { setRequirementsTraversalDirtyBit<Compositing::NeedsPaintOrderChildrenUpdate>(); } |
| 280 | void setNeedsPostLayoutCompositingUpdate() { setRequirementsTraversalDirtyBit<Compositing::NeedsPostLayoutUpdate>(); } |
| 281 | void setDescendantsNeedCompositingRequirementsTraversal() { setRequirementsTraversalDirtyBit<Compositing::DescendantsNeedRequirementsTraversal>(); } |
| 282 | void setSubsequentLayersNeedCompositingRequirementsTraversal() { setRequirementsTraversalDirtyBit<Compositing::SubsequentLayersNeedRequirementsTraversal>(); } |
| 283 | |
| 284 | void setNeedsPostLayoutCompositingUpdateOnAncestors() { setAncestorsHaveCompositingDirtyFlag(Compositing::NeedsPostLayoutUpdate); } |
| 285 | |
| 286 | template<Compositing V> |
| 287 | void setBackingAndHierarchyTraversalDirtyBit() |
| 288 | { |
| 289 | m_compositingDirtyBits.add(V); |
| 290 | setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal); |
| 291 | } |
| 292 | |
| 293 | void setNeedsCompositingLayerConnection() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsLayerConnection>(); } |
| 294 | void setNeedsCompositingGeometryUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsGeometryUpdate>(); } |
| 295 | void setNeedsCompositingConfigurationUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsConfigurationUpdate>(); } |
| 296 | void setNeedsScrollingTreeUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsScrollingTreeUpdate>(); } |
| 297 | void setChildrenNeedCompositingGeometryUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::ChildrenNeedGeometryUpdate>(); } |
| 298 | void setDescendantsNeedUpdateBackingAndHierarchyTraversal() { setBackingAndHierarchyTraversalDirtyBit<Compositing::DescendantsNeedBackingAndHierarchyTraversal>(); } |
| 299 | |
| 300 | void setNeedsCompositingGeometryUpdateOnAncestors() { setAncestorsHaveCompositingDirtyFlag(Compositing::NeedsGeometryUpdate); } |
| 301 | |
| 302 | bool needsCompositingRequirementsTraversal() const { return m_compositingDirtyBits.containsAny(computeCompositingRequirementsFlags()); } |
| 303 | void clearCompositingRequirementsTraversalState() |
| 304 | { |
| 305 | m_compositingDirtyBits.remove(Compositing::HasDescendantNeedingRequirementsTraversal); |
| 306 | m_compositingDirtyBits.remove(computeCompositingRequirementsFlags()); |
| 307 | } |
| 308 | |
| 309 | bool needsUpdateBackingOrHierarchyTraversal() const { return m_compositingDirtyBits.containsAny(updateBackingOrHierarchyFlags()); } |
| 310 | void clearUpdateBackingOrHierarchyTraversalState() |
| 311 | { |
| 312 | m_compositingDirtyBits.remove(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal); |
| 313 | m_compositingDirtyBits.remove(updateBackingOrHierarchyFlags()); |
| 314 | } |
| 315 | |
| 316 | bool needsAnyCompositingTraversal() const { return !m_compositingDirtyBits.isEmpty(); } |
| 317 | void clearCompositingPaintOrderState() { m_compositingDirtyBits = { }; } |
| 318 | |
| 319 | class LayerList { |
| 320 | friend class RenderLayer; |
| 321 | public: |
| 322 | using iterator = RenderLayer**; |
| 323 | using const_iterator = RenderLayer * const *; |
| 324 | using reverse_iterator = std::reverse_iterator<iterator>; |
| 325 | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
| 326 | |
| 327 | iterator begin() { return m_layerList ? m_layerList->begin() : nullptr; } |
| 328 | iterator end() { return m_layerList ? m_layerList->end() : nullptr; } |
| 329 | |
| 330 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
| 331 | reverse_iterator rend() { return reverse_iterator(begin()); } |
| 332 | |
| 333 | const_iterator begin() const { return m_layerList ? m_layerList->begin() : nullptr; } |
| 334 | const_iterator end() const { return m_layerList ? m_layerList->end() : nullptr; } |
| 335 | |
| 336 | const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } |
| 337 | const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } |
| 338 | |
| 339 | size_t size() const { return m_layerList ? m_layerList->size() : 0; } |
| 340 | |
| 341 | private: |
| 342 | LayerList(Vector<RenderLayer*>* layerList) |
| 343 | : m_layerList(layerList) |
| 344 | { |
| 345 | } |
| 346 | |
| 347 | Vector<RenderLayer*>* m_layerList; |
| 348 | }; |
| 349 | |
| 350 | LayerList normalFlowLayers() const |
| 351 | { |
| 352 | ASSERT(!m_normalFlowListDirty); |
| 353 | return LayerList(m_normalFlowList.get()); |
| 354 | } |
| 355 | |
| 356 | LayerList positiveZOrderLayers() const |
| 357 | { |
| 358 | ASSERT(!m_zOrderListsDirty); |
| 359 | ASSERT(isStackingContext() || !m_posZOrderList); |
| 360 | return LayerList(m_posZOrderList.get()); |
| 361 | } |
| 362 | |
| 363 | bool hasNegativeZOrderLayers() const |
| 364 | { |
| 365 | return m_negZOrderList && m_negZOrderList->size(); |
| 366 | } |
| 367 | |
| 368 | LayerList negativeZOrderLayers() const |
| 369 | { |
| 370 | ASSERT(!m_zOrderListsDirty); |
| 371 | ASSERT(isStackingContext() || !m_negZOrderList); |
| 372 | return LayerList(m_negZOrderList.get()); |
| 373 | } |
| 374 | |
| 375 | // Update our normal and z-index lists. |
| 376 | void updateLayerListsIfNeeded(); |
| 377 | void updateDescendantDependentFlags(); |
| 378 | bool descendantDependentFlagsAreDirty() const |
| 379 | { |
| 380 | return m_visibleDescendantStatusDirty || m_visibleContentStatusDirty || m_hasSelfPaintingLayerDescendantDirty |
| 381 | #if ENABLE(CSS_COMPOSITING) |
| 382 | || m_hasNotIsolatedBlendingDescendantsStatusDirty |
| 383 | #endif |
| 384 | ; |
| 385 | } |
| 386 | |
| 387 | void repaintIncludingDescendants(); |
| 388 | |
| 389 | // Indicate that the layer contents need to be repainted. Only has an effect |
| 390 | // if layer compositing is being used. |
| 391 | void setBackingNeedsRepaint(GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer); |
| 392 | |
| 393 | // The rect is in the coordinate space of the layer's render object. |
| 394 | void setBackingNeedsRepaintInRect(const LayoutRect&, GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer); |
| 395 | void repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer); |
| 396 | |
| 397 | void styleChanged(StyleDifference, const RenderStyle* oldStyle); |
| 398 | |
| 399 | RenderMarquee* marquee() const { return m_marquee.get(); } |
| 400 | |
| 401 | bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; } |
| 402 | |
| 403 | bool cannotBlitToWindow() const; |
| 404 | |
| 405 | bool isTransparent() const { return renderer().isTransparent() || renderer().hasMask(); } |
| 406 | |
| 407 | bool hasReflection() const { return renderer().hasReflection(); } |
| 408 | bool isReflection() const { return renderer().isReplica(); } |
| 409 | RenderReplica* reflection() const { return m_reflection.get(); } |
| 410 | RenderLayer* reflectionLayer() const; |
| 411 | bool isReflectionLayer(const RenderLayer&) const; |
| 412 | |
| 413 | const LayoutPoint& location() const { return m_topLeft; } |
| 414 | void setLocation(const LayoutPoint& p) { m_topLeft = p; } |
| 415 | |
| 416 | const IntSize& size() const { return m_layerSize; } |
| 417 | void setSize(const IntSize& size) { m_layerSize = size; } // Only public for RenderTreeAsText. |
| 418 | |
| 419 | LayoutRect rect() const { return LayoutRect(location(), size()); } |
| 420 | |
| 421 | IntSize visibleSize() const override; |
| 422 | IntSize contentsSize() const override; |
| 423 | IntSize reachableTotalContentsSize() const override; |
| 424 | |
| 425 | int scrollWidth() const; |
| 426 | int scrollHeight() const; |
| 427 | |
| 428 | void panScrollFromPoint(const IntPoint&); |
| 429 | |
| 430 | // Scrolling methods for layers that can scroll their overflow. |
| 431 | void scrollByRecursively(const IntSize& delta, ScrollableArea** scrolledArea = nullptr); |
| 432 | |
| 433 | WEBCORE_EXPORT void scrollToOffset(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped); |
| 434 | |
| 435 | void scrollToXPosition(int x, ScrollType, ScrollClamping = ScrollClamping::Clamped); |
| 436 | void scrollToYPosition(int y, ScrollType, ScrollClamping = ScrollClamping::Clamped); |
| 437 | |
| 438 | // These are only used by marquee. |
| 439 | void scrollToXOffset(int x) { scrollToOffset(ScrollOffset(x, scrollOffset().y()), ScrollType::Programmatic, ScrollClamping::Unclamped); } |
| 440 | void scrollToYOffset(int y) { scrollToOffset(ScrollOffset(scrollOffset().x(), y), ScrollType::Programmatic, ScrollClamping::Unclamped); } |
| 441 | |
| 442 | void setPostLayoutScrollPosition(Optional<ScrollPosition>); |
| 443 | void applyPostLayoutScrollPositionIfNeeded(); |
| 444 | |
| 445 | ScrollOffset scrollOffset() const { return scrollOffsetFromPosition(m_scrollPosition); } |
| 446 | |
| 447 | void availableContentSizeChanged(AvailableSizeChangeReason) override; |
| 448 | |
| 449 | // "absoluteRect" is in scaled document coordinates. |
| 450 | void scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions&); |
| 451 | |
| 452 | bool scrollsOverflow() const; |
| 453 | bool hasScrollbars() const { return m_hBar || m_vBar; } |
| 454 | void setHasHorizontalScrollbar(bool); |
| 455 | void setHasVerticalScrollbar(bool); |
| 456 | |
| 457 | Ref<Scrollbar> createScrollbar(ScrollbarOrientation); |
| 458 | void destroyScrollbar(ScrollbarOrientation); |
| 459 | |
| 460 | bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } |
| 461 | bool hasVerticalScrollbar() const { return verticalScrollbar(); } |
| 462 | |
| 463 | bool horizontalScrollbarHiddenByStyle() const override; |
| 464 | bool verticalScrollbarHiddenByStyle() const override; |
| 465 | |
| 466 | // ScrollableArea overrides |
| 467 | ScrollPosition scrollPosition() const override { return m_scrollPosition; } |
| 468 | |
| 469 | Scrollbar* horizontalScrollbar() const override { return m_hBar.get(); } |
| 470 | Scrollbar* verticalScrollbar() const override { return m_vBar.get(); } |
| 471 | ScrollableArea* enclosingScrollableArea() const override; |
| 472 | |
| 473 | bool isScrollableOrRubberbandable() override; |
| 474 | bool hasScrollableOrRubberbandableAncestor() override; |
| 475 | bool useDarkAppearance() const final; |
| 476 | #if ENABLE(CSS_SCROLL_SNAP) |
| 477 | void updateSnapOffsets() override; |
| 478 | #endif |
| 479 | |
| 480 | bool requiresScrollPositionReconciliation() const { return m_requiresScrollPositionReconciliation; } |
| 481 | void setRequiresScrollPositionReconciliation(bool requiresReconciliation = true) { m_requiresScrollPositionReconciliation = requiresReconciliation; } |
| 482 | |
| 483 | #if PLATFORM(IOS_FAMILY) |
| 484 | #if ENABLE(IOS_TOUCH_EVENTS) |
| 485 | bool handleTouchEvent(const PlatformTouchEvent&) override; |
| 486 | #endif |
| 487 | |
| 488 | void didStartScroll() override; |
| 489 | void didEndScroll() override; |
| 490 | void didUpdateScroll() override; |
| 491 | #endif |
| 492 | |
| 493 | // Returns true when the layer could do touch scrolling, but doesn't look at whether there is actually scrollable overflow. |
| 494 | bool canUseCompositedScrolling() const; |
| 495 | // Returns true when there is actually scrollable overflow (requires layout to be up-to-date). |
| 496 | bool hasCompositedScrollableOverflow() const; |
| 497 | |
| 498 | int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; |
| 499 | int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; |
| 500 | |
| 501 | bool hasOverflowControls() const; |
| 502 | bool isPointInResizeControl(const IntPoint& absolutePoint) const; |
| 503 | bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint); |
| 504 | IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const; |
| 505 | |
| 506 | void paintOverflowControls(GraphicsContext&, const IntPoint&, const IntRect& damageRect, bool paintingOverlayControls = false); |
| 507 | void paintScrollCorner(GraphicsContext&, const IntPoint&, const IntRect& damageRect); |
| 508 | void paintResizer(GraphicsContext&, const LayoutPoint&, const LayoutRect& damageRect); |
| 509 | |
| 510 | void updateScrollInfoAfterLayout(); |
| 511 | |
| 512 | bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1); |
| 513 | void autoscroll(const IntPoint&); |
| 514 | |
| 515 | bool canResize() const; |
| 516 | void resize(const PlatformMouseEvent&, const LayoutSize&); |
| 517 | bool inResizeMode() const { return m_inResizeMode; } |
| 518 | void setInResizeMode(bool b) { m_inResizeMode = b; } |
| 519 | |
| 520 | bool isRenderViewLayer() const { return m_isRenderViewLayer; } |
| 521 | bool isForcedStackingContext() const { return m_forcedStackingContext; } |
| 522 | bool isOpportunisticStackingContext() const { return m_isOpportunisticStackingContext; } |
| 523 | |
| 524 | RenderLayerCompositor& compositor() const; |
| 525 | |
| 526 | // Notification from the renderer that its content changed (e.g. current frame of image changed). |
| 527 | // Allows updates of layer content without repainting. |
| 528 | void contentChanged(ContentChangeType); |
| 529 | |
| 530 | bool canRender3DTransforms() const; |
| 531 | |
| 532 | enum UpdateLayerPositionsFlag { |
| 533 | CheckForRepaint = 1 << 0, |
| 534 | NeedsFullRepaintInBacking = 1 << 1, |
| 535 | ContainingClippingLayerChangedSize = 1 << 2, |
| 536 | = 1 << 3, |
| 537 | SeenTransformedLayer = 1 << 4, |
| 538 | Seen3DTransformedLayer = 1 << 5, |
| 539 | SeenCompositedScrollingLayer = 1 << 6, |
| 540 | }; |
| 541 | static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint }; } |
| 542 | |
| 543 | void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, OptionSet<UpdateLayerPositionsFlag>); |
| 544 | |
| 545 | void updateLayerPositionsAfterOverflowScroll(); |
| 546 | void updateLayerPositionsAfterDocumentScroll(); |
| 547 | |
| 548 | bool () const; |
| 549 | enum { ExcludeCompositedPaginatedLayers, IncludeCompositedPaginatedLayers }; |
| 550 | RenderLayer* (PaginationInclusionMode mode) const |
| 551 | { |
| 552 | if (mode == ExcludeCompositedPaginatedLayers && hasCompositedLayerInEnclosingPaginationChain()) |
| 553 | return nullptr; |
| 554 | return m_enclosingPaginationLayer.get(); |
| 555 | } |
| 556 | |
| 557 | void updateTransform(); |
| 558 | |
| 559 | #if ENABLE(CSS_COMPOSITING) |
| 560 | void updateBlendMode(); |
| 561 | #endif |
| 562 | |
| 563 | const LayoutSize& offsetForInFlowPosition() const { return m_offsetForInFlowPosition; } |
| 564 | |
| 565 | void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes); |
| 566 | void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes); |
| 567 | |
| 568 | void addBlockSelectionGapsBounds(const LayoutRect&); |
| 569 | void clearBlockSelectionGapsBounds(); |
| 570 | void repaintBlockSelectionGaps(); |
| 571 | |
| 572 | // FIXME: We should ASSERT(!m_visibleContentStatusDirty) here, but see https://bugs.webkit.org/show_bug.cgi?id=71044 |
| 573 | // ditto for hasVisibleDescendant(), see https://bugs.webkit.org/show_bug.cgi?id=71277 |
| 574 | bool hasVisibleContent() const { return m_hasVisibleContent; } |
| 575 | bool hasVisibleDescendant() const { return m_hasVisibleDescendant; } |
| 576 | |
| 577 | void setHasVisibleContent(); |
| 578 | void dirtyVisibleContentStatus(); |
| 579 | |
| 580 | bool hasVisibleBoxDecorationsOrBackground() const; |
| 581 | bool hasVisibleBoxDecorations() const; |
| 582 | |
| 583 | struct PaintedContentRequest { |
| 584 | void makeStatesUndetermined() |
| 585 | { |
| 586 | if (hasPaintedContent == RequestState::Unknown) |
| 587 | hasPaintedContent = RequestState::Undetermined; |
| 588 | |
| 589 | if (hasSubpixelAntialiasedText == RequestState::Unknown) |
| 590 | hasSubpixelAntialiasedText = RequestState::Undetermined; |
| 591 | } |
| 592 | |
| 593 | void setHasPaintedContent() { hasPaintedContent = RequestState::True; } |
| 594 | void setHasSubpixelAntialiasedText() { hasSubpixelAntialiasedText = RequestState::True; } |
| 595 | |
| 596 | bool needToDeterminePaintedContentState() const { return hasPaintedContent == RequestState::Unknown; } |
| 597 | bool needToDetermineSubpixelAntialiasedTextState() const { return hasSubpixelAntialiasedText == RequestState::Unknown; } |
| 598 | |
| 599 | bool probablyHasPaintedContent() const { return hasPaintedContent == RequestState::True || hasPaintedContent == RequestState::Undetermined; } |
| 600 | bool probablyHasSubpixelAntialiasedText() const { return hasSubpixelAntialiasedText == RequestState::True || hasSubpixelAntialiasedText == RequestState::Undetermined; } |
| 601 | |
| 602 | bool isSatisfied() const { return hasPaintedContent != RequestState::Unknown && hasSubpixelAntialiasedText != RequestState::Unknown; } |
| 603 | |
| 604 | RequestState hasPaintedContent { RequestState::Unknown }; |
| 605 | RequestState hasSubpixelAntialiasedText { RequestState::DontCare }; |
| 606 | }; |
| 607 | |
| 608 | // Returns true if this layer has visible content (ignoring any child layers). |
| 609 | bool isVisuallyNonEmpty(PaintedContentRequest* = nullptr) const; |
| 610 | // True if this layer container renderers that paint. |
| 611 | bool hasNonEmptyChildRenderers(PaintedContentRequest&) const; |
| 612 | |
| 613 | // FIXME: We should ASSERT(!m_hasSelfPaintingLayerDescendantDirty); here but we hit the same bugs as visible content above. |
| 614 | // Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates. |
| 615 | bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; } |
| 616 | |
| 617 | bool ancestorLayerIsInContainingBlockChain(const RenderLayer& ancestor, const RenderLayer* checkLimit = nullptr) const; |
| 618 | |
| 619 | // Gets the nearest enclosing positioned ancestor layer (also includes |
| 620 | // the <html> layer and the root layer). |
| 621 | RenderLayer* enclosingAncestorForPosition(PositionType) const; |
| 622 | |
| 623 | // Returns the nearest enclosing layer that is scrollable. |
| 624 | RenderLayer* enclosingScrollableLayer() const; |
| 625 | |
| 626 | // The layer relative to which clipping rects for this layer are computed. |
| 627 | RenderLayer* clippingRootForPainting() const; |
| 628 | |
| 629 | RenderLayer* enclosingOverflowClipLayer(IncludeSelfOrNot) const; |
| 630 | |
| 631 | // Enclosing compositing layer; if includeSelf is true, may return this. |
| 632 | RenderLayer* enclosingCompositingLayer(IncludeSelfOrNot = IncludeSelf) const; |
| 633 | RenderLayer* enclosingCompositingLayerForRepaint(IncludeSelfOrNot = IncludeSelf) const; |
| 634 | // Ancestor compositing layer, excluding this. |
| 635 | RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(ExcludeSelf); } |
| 636 | |
| 637 | RenderLayer* enclosingFilterLayer(IncludeSelfOrNot = IncludeSelf) const; |
| 638 | RenderLayer* enclosingFilterRepaintLayer() const; |
| 639 | void setFilterBackendNeedsRepaintingInRect(const LayoutRect&); |
| 640 | bool hasAncestorWithFilterOutsets() const; |
| 641 | |
| 642 | bool canUseConvertToLayerCoords() const |
| 643 | { |
| 644 | // These RenderObject have an impact on their layers' without them knowing about it. |
| 645 | return !renderer().hasTransform() && !renderer().isSVGRoot(); |
| 646 | } |
| 647 | |
| 648 | // FIXME: adjustForColumns allows us to position compositing layers in columns correctly, but eventually they need to be split across columns too. |
| 649 | enum ColumnOffsetAdjustment { DontAdjustForColumns, AdjustForColumns }; |
| 650 | void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location, ColumnOffsetAdjustment adjustForColumns = DontAdjustForColumns) const; |
| 651 | LayoutPoint convertToLayerCoords(const RenderLayer* ancestorLayer, const LayoutPoint&, ColumnOffsetAdjustment adjustForColumns = DontAdjustForColumns) const; |
| 652 | LayoutSize offsetFromAncestor(const RenderLayer*, ColumnOffsetAdjustment = DontAdjustForColumns) const; |
| 653 | |
| 654 | int zIndex() const { return renderer().style().zIndex(); } |
| 655 | |
| 656 | enum PaintLayerFlag { |
| 657 | PaintLayerHaveTransparency = 1 << 0, |
| 658 | PaintLayerAppliedTransform = 1 << 1, |
| 659 | PaintLayerTemporaryClipRects = 1 << 2, |
| 660 | PaintLayerPaintingReflection = 1 << 3, |
| 661 | PaintLayerPaintingOverlayScrollbars = 1 << 4, |
| 662 | PaintLayerPaintingCompositingBackgroundPhase = 1 << 5, |
| 663 | PaintLayerPaintingCompositingForegroundPhase = 1 << 6, |
| 664 | PaintLayerPaintingCompositingMaskPhase = 1 << 7, |
| 665 | PaintLayerPaintingCompositingClipPathPhase = 1 << 8, |
| 666 | PaintLayerPaintingCompositingScrollingPhase = 1 << 9, |
| 667 | PaintLayerPaintingOverflowContents = 1 << 10, |
| 668 | PaintLayerPaintingRootBackgroundOnly = 1 << 11, |
| 669 | PaintLayerPaintingSkipRootBackground = 1 << 12, |
| 670 | PaintLayerPaintingChildClippingMaskPhase = 1 << 13, |
| 671 | PaintLayerCollectingEventRegion = 1 << 14, |
| 672 | }; |
| 673 | static constexpr OptionSet<PaintLayerFlag> paintLayerPaintingCompositingAllPhasesFlags() { return { PaintLayerPaintingCompositingBackgroundPhase, PaintLayerPaintingCompositingForegroundPhase }; } |
| 674 | |
| 675 | enum class SecurityOriginPaintPolicy { AnyOrigin, AccessibleOriginOnly }; |
| 676 | |
| 677 | // The two main functions that use the layer system. The paint method |
| 678 | // paints the layers that intersect the damage rect from back to |
| 679 | // front. The hitTest method looks for mouse events by walking |
| 680 | // layers that intersect the point from front to back. |
| 681 | void paint(GraphicsContext&, const LayoutRect& damageRect, const LayoutSize& subpixelOffset = LayoutSize(), OptionSet<PaintBehavior> = PaintBehavior::Normal, |
| 682 | RenderObject* subtreePaintRoot = nullptr, OptionSet<PaintLayerFlag> = { }, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin); |
| 683 | bool hitTest(const HitTestRequest&, HitTestResult&); |
| 684 | bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&); |
| 685 | void paintOverlayScrollbars(GraphicsContext&, const LayoutRect& damageRect, OptionSet<PaintBehavior>, RenderObject* subtreePaintRoot = nullptr); |
| 686 | |
| 687 | struct ClipRectsContext { |
| 688 | ClipRectsContext(const RenderLayer* inRootLayer, ClipRectsType inClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip inRespectOverflowClip = RespectOverflowClip) |
| 689 | : rootLayer(inRootLayer) |
| 690 | , clipRectsType(inClipRectsType) |
| 691 | , overlayScrollbarSizeRelevancy(inOverlayScrollbarSizeRelevancy) |
| 692 | , respectOverflowClip(inRespectOverflowClip) |
| 693 | { } |
| 694 | const RenderLayer* rootLayer; |
| 695 | ClipRectsType clipRectsType; |
| 696 | OverlayScrollbarSizeRelevancy overlayScrollbarSizeRelevancy; |
| 697 | ShouldRespectOverflowClip respectOverflowClip; |
| 698 | }; |
| 699 | |
| 700 | // This method figures out our layerBounds in coordinates relative to |
| 701 | // |rootLayer}. It also computes our background and foreground clip rects |
| 702 | // for painting/event handling. |
| 703 | // Pass offsetFromRoot if known. |
| 704 | void calculateRects(const ClipRectsContext&, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, |
| 705 | ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutSize& offsetFromRoot) const; |
| 706 | |
| 707 | // Public just for RenderTreeAsText. |
| 708 | void (LayerFragments&, const RenderLayer* rootLayer, const LayoutRect& dirtyRect, |
| 709 | PaginationInclusionMode, |
| 710 | ClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip, const LayoutSize& offsetFromRoot, |
| 711 | const LayoutRect* layerBoundingBox = nullptr, ShouldApplyRootOffsetToFragments = IgnoreRootOffsetForFragments); |
| 712 | |
| 713 | LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space. |
| 714 | LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space. |
| 715 | LayoutRect localClipRect(bool& clipExceedsBounds) const; // Returns the background clip rect of the layer in the local coordinate space. |
| 716 | |
| 717 | bool clipCrossesPaintingBoundary() const; |
| 718 | |
| 719 | // Pass offsetFromRoot if known. |
| 720 | bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot, const LayoutRect* cachedBoundingBox = nullptr) const; |
| 721 | |
| 722 | enum CalculateLayerBoundsFlag { |
| 723 | IncludeSelfTransform = 1 << 0, |
| 724 | UseLocalClipRectIfPossible = 1 << 1, |
| 725 | IncludeFilterOutsets = 1 << 2, |
| 726 | IncludePaintedFilterOutsets = 1 << 3, |
| 727 | ExcludeHiddenDescendants = 1 << 4, |
| 728 | DontConstrainForMask = 1 << 5, |
| 729 | IncludeCompositedDescendants = 1 << 6, |
| 730 | UseFragmentBoxesExcludingCompositing = 1 << 7, |
| 731 | UseFragmentBoxesIncludingCompositing = 1 << 8, |
| 732 | }; |
| 733 | static constexpr OptionSet<CalculateLayerBoundsFlag> defaultCalculateLayerBoundsFlags() { return { IncludeSelfTransform, UseLocalClipRectIfPossible, IncludePaintedFilterOutsets, UseFragmentBoxesExcludingCompositing }; } |
| 734 | |
| 735 | // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known. |
| 736 | LayoutRect boundingBox(const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot = LayoutSize(), OptionSet<CalculateLayerBoundsFlag> = { }) const; |
| 737 | // Bounding box in the coordinates of this layer. |
| 738 | LayoutRect localBoundingBox(OptionSet<CalculateLayerBoundsFlag> = { }) const; |
| 739 | // Deprecated: Pixel snapped bounding box relative to the root. |
| 740 | WEBCORE_EXPORT IntRect absoluteBoundingBox() const; |
| 741 | // Device pixel snapped bounding box relative to the root. absoluteBoundingBox() callers will be directed to this. |
| 742 | FloatRect absoluteBoundingBoxForPainting() const; |
| 743 | |
| 744 | // Bounds used for layer overlap testing in RenderLayerCompositor. |
| 745 | LayoutRect overlapBounds() const; |
| 746 | |
| 747 | // Takes transform animations into account, returning true if they could be cheaply computed. |
| 748 | // Unlike overlapBounds, these bounds include descendant layers. |
| 749 | bool getOverlapBoundsIncludingChildrenAccountingForTransformAnimations(LayoutRect&, OptionSet<CalculateLayerBoundsFlag> additionalFlags = { }) const; |
| 750 | |
| 751 | // If true, this layer's children are included in its bounds for overlap testing. |
| 752 | // We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around. |
| 753 | bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer().style().filter().hasFilterThatMovesPixels(); } |
| 754 | |
| 755 | // Can pass offsetFromRoot if known. |
| 756 | LayoutRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, OptionSet<CalculateLayerBoundsFlag> = defaultCalculateLayerBoundsFlags()) const; |
| 757 | |
| 758 | // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint. |
| 759 | bool hasComputedRepaintRects() const { return renderer().hasRepaintLayoutRects(); } |
| 760 | LayoutRect repaintRectIncludingNonCompositingDescendants() const; |
| 761 | |
| 762 | void setRepaintStatus(RepaintStatus status) { m_repaintStatus = status; } |
| 763 | RepaintStatus repaintStatus() const { return static_cast<RepaintStatus>(m_repaintStatus); } |
| 764 | |
| 765 | LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; } |
| 766 | LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; } |
| 767 | |
| 768 | void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; } |
| 769 | void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; } |
| 770 | |
| 771 | #if PLATFORM(IOS_FAMILY) |
| 772 | bool adjustForIOSCaretWhenScrolling() const { return m_adjustForIOSCaretWhenScrolling; } |
| 773 | void setAdjustForIOSCaretWhenScrolling(bool adjustForIOSCaretWhenScrolling) { m_adjustForIOSCaretWhenScrolling = adjustForIOSCaretWhenScrolling; } |
| 774 | #endif |
| 775 | |
| 776 | bool hasTransform() const { return renderer().hasTransform(); } |
| 777 | // Note that this transform has the transform-origin baked in. |
| 778 | TransformationMatrix* transform() const { return m_transform.get(); } |
| 779 | // currentTransform computes a transform which takes accelerated animations into account. The |
| 780 | // resulting transform has transform-origin baked in. If the layer does not have a transform, |
| 781 | // returns the identity matrix. |
| 782 | TransformationMatrix currentTransform(RenderStyle::ApplyTransformOrigin = RenderStyle::IncludeTransformOrigin) const; |
| 783 | TransformationMatrix renderableTransform(OptionSet<PaintBehavior>) const; |
| 784 | |
| 785 | // Get the perspective transform, which is applied to transformed sublayers. |
| 786 | // Returns true if the layer has a -webkit-perspective. |
| 787 | // Note that this transform has the perspective-origin baked in. |
| 788 | TransformationMatrix perspectiveTransform() const; |
| 789 | FloatPoint perspectiveOrigin() const; |
| 790 | bool preserves3D() const { return renderer().style().transformStyle3D() == TransformStyle3D::Preserve3D; } |
| 791 | bool has3DTransform() const { return m_transform && !m_transform->isAffine(); } |
| 792 | |
| 793 | void filterNeedsRepaint(); |
| 794 | bool hasFilter() const { return renderer().hasFilter(); } |
| 795 | bool hasBackdropFilter() const |
| 796 | { |
| 797 | #if ENABLE(FILTERS_LEVEL_2) |
| 798 | return renderer().hasBackdropFilter(); |
| 799 | #else |
| 800 | return false; |
| 801 | #endif |
| 802 | } |
| 803 | |
| 804 | #if ENABLE(CSS_COMPOSITING) |
| 805 | bool hasBlendMode() const { return renderer().hasBlendMode(); } |
| 806 | BlendMode blendMode() const { return static_cast<BlendMode>(m_blendMode); } |
| 807 | |
| 808 | bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isCSSStackingContext(); } |
| 809 | bool hasNotIsolatedCompositedBlendingDescendants() const { return m_hasNotIsolatedCompositedBlendingDescendants; } |
| 810 | void setHasNotIsolatedCompositedBlendingDescendants(bool hasNotIsolatedCompositedBlendingDescendants) |
| 811 | { |
| 812 | m_hasNotIsolatedCompositedBlendingDescendants = hasNotIsolatedCompositedBlendingDescendants; |
| 813 | } |
| 814 | |
| 815 | bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isCSSStackingContext(); } |
| 816 | |
| 817 | // FIXME: We should ASSERT(!m_hasNotIsolatedBlendingDescendantsStatusDirty); here but we hit the same bugs as visible content above. |
| 818 | bool hasNotIsolatedBlendingDescendants() const { return m_hasNotIsolatedBlendingDescendants; } |
| 819 | bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return m_hasNotIsolatedBlendingDescendantsStatusDirty; } |
| 820 | #else |
| 821 | bool hasBlendMode() const { return false; } |
| 822 | bool isolatesCompositedBlending() const { return false; } |
| 823 | bool isolatesBlending() const { return false; } |
| 824 | bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return false; } |
| 825 | #endif |
| 826 | |
| 827 | bool isComposited() const { return m_backing != nullptr; } |
| 828 | bool hasCompositingDescendant() const { return m_hasCompositingDescendant; } |
| 829 | bool hasCompositedMask() const; |
| 830 | |
| 831 | // If non-null, a non-ancestor composited layer that this layer paints into (it is sharing its backing store with this layer). |
| 832 | RenderLayer* backingProviderLayer() const { return m_backingProviderLayer.get(); } |
| 833 | void setBackingProviderLayer(RenderLayer*); |
| 834 | void disconnectFromBackingProviderLayer(); |
| 835 | |
| 836 | bool paintsIntoProvidedBacking() const { return !!m_backingProviderLayer; } |
| 837 | |
| 838 | RenderLayerBacking* backing() const { return m_backing.get(); } |
| 839 | RenderLayerBacking* ensureBacking(); |
| 840 | void clearBacking(bool layerBeingDestroyed = false); |
| 841 | |
| 842 | GraphicsLayer* layerForHorizontalScrollbar() const override; |
| 843 | GraphicsLayer* layerForVerticalScrollbar() const override; |
| 844 | GraphicsLayer* layerForScrollCorner() const override; |
| 845 | |
| 846 | bool usesCompositedScrolling() const override; |
| 847 | bool usesAsyncScrolling() const override; |
| 848 | |
| 849 | bool hasCompositedScrollingAncestor() const { return m_hasCompositedScrollingAncestor; } |
| 850 | void setHasCompositedScrollingAncestor(bool hasCompositedScrollingAncestor) { m_hasCompositedScrollingAncestor = hasCompositedScrollingAncestor; } |
| 851 | |
| 852 | bool paintsWithTransparency(OptionSet<PaintBehavior> paintBehavior) const |
| 853 | { |
| 854 | return (isTransparent() || hasBlendMode() || (isolatesBlending() && !renderer().isDocumentElementRenderer())) && ((paintBehavior & PaintBehavior::FlattenCompositingLayers) || !isComposited()); |
| 855 | } |
| 856 | |
| 857 | bool paintsWithTransform(OptionSet<PaintBehavior>) const; |
| 858 | bool shouldPaintMask(OptionSet<PaintBehavior>, OptionSet<PaintLayerFlag>) const; |
| 859 | bool shouldApplyClipPath(OptionSet<PaintBehavior>, OptionSet<PaintLayerFlag>) const; |
| 860 | |
| 861 | // Returns true if background phase is painted opaque in the given rect. |
| 862 | // The query rect is given in local coordinates. |
| 863 | bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const; |
| 864 | |
| 865 | bool scrollingMayRevealBackground() const; |
| 866 | |
| 867 | bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; } |
| 868 | void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; } |
| 869 | |
| 870 | bool paintsWithFilters() const; |
| 871 | bool requiresFullLayerImageForFilters() const; |
| 872 | |
| 873 | Element* enclosingElement() const; |
| 874 | |
| 875 | enum ViewportConstrainedNotCompositedReason { |
| 876 | NoNotCompositedReason, |
| 877 | NotCompositedForBoundsOutOfView, |
| 878 | NotCompositedForNonViewContainer, |
| 879 | NotCompositedForNoVisibleContent, |
| 880 | }; |
| 881 | |
| 882 | void setViewportConstrainedNotCompositedReason(ViewportConstrainedNotCompositedReason reason) { m_viewportConstrainedNotCompositedReason = reason; } |
| 883 | ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason() const { return static_cast<ViewportConstrainedNotCompositedReason>(m_viewportConstrainedNotCompositedReason); } |
| 884 | |
| 885 | IndirectCompositingReason indirectCompositingReason() const { return static_cast<IndirectCompositingReason>(m_indirectCompositingReason); } |
| 886 | |
| 887 | bool isRenderFragmentedFlow() const { return renderer().isRenderFragmentedFlow(); } |
| 888 | bool isOutOfFlowRenderFragmentedFlow() const { return renderer().isOutOfFlowRenderFragmentedFlow(); } |
| 889 | bool isInsideFragmentedFlow() const { return renderer().fragmentedFlowState() != RenderObject::NotInsideFragmentedFlow; } |
| 890 | bool isDirtyRenderFragmentedFlow() const |
| 891 | { |
| 892 | ASSERT(isRenderFragmentedFlow()); |
| 893 | return zOrderListsDirty() || normalFlowListDirty(); |
| 894 | } |
| 895 | |
| 896 | RenderLayer* enclosingFragmentedFlowAncestor() const; |
| 897 | |
| 898 | bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return renderer().shouldPlaceBlockDirectionScrollbarOnLeft(); } |
| 899 | |
| 900 | void simulateFrequentPaint() { SinglePaintFrequencyTracking { m_paintFrequencyTracker }; } |
| 901 | bool paintingFrequently() const { return m_paintFrequencyTracker.paintingFrequently(); } |
| 902 | |
| 903 | WEBCORE_EXPORT bool isTransparentOrFullyClippedRespectingParentFrames() const; |
| 904 | |
| 905 | void invalidateEventRegion(); |
| 906 | |
| 907 | private: |
| 908 | |
| 909 | void setNextSibling(RenderLayer* next) { m_next = next; } |
| 910 | void setPreviousSibling(RenderLayer* prev) { m_previous = prev; } |
| 911 | void setParent(RenderLayer*); |
| 912 | void setFirstChild(RenderLayer* first) { m_first = first; } |
| 913 | void setLastChild(RenderLayer* last) { m_last = last; } |
| 914 | |
| 915 | void dirtyPaintOrderListsOnChildChange(RenderLayer&); |
| 916 | |
| 917 | bool shouldBeNormalFlowOnly() const; |
| 918 | bool shouldBeCSSStackingContext() const; |
| 919 | |
| 920 | // Return true if changed. |
| 921 | bool setIsNormalFlowOnly(bool); |
| 922 | |
| 923 | bool setIsOpportunisticStackingContext(bool); |
| 924 | bool setIsCSSStackingContext(bool); |
| 925 | |
| 926 | void isStackingContextChanged(); |
| 927 | |
| 928 | bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); } |
| 929 | |
| 930 | void updateZOrderLists(); |
| 931 | void rebuildZOrderLists(); |
| 932 | void rebuildZOrderLists(std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&); |
| 933 | void collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&); |
| 934 | void clearZOrderLists(); |
| 935 | |
| 936 | void updateNormalFlowList(); |
| 937 | |
| 938 | struct LayerPaintingInfo { |
| 939 | LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, OptionSet<PaintBehavior> inPaintBehavior, const LayoutSize& inSubpixelOffset, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr, bool inRequireSecurityOriginAccessForWidgets = false) |
| 940 | : rootLayer(inRootLayer) |
| 941 | , subtreePaintRoot(inSubtreePaintRoot) |
| 942 | , paintDirtyRect(inDirtyRect) |
| 943 | , subpixelOffset(inSubpixelOffset) |
| 944 | , overlapTestRequests(inOverlapTestRequests) |
| 945 | , paintBehavior(inPaintBehavior) |
| 946 | , requireSecurityOriginAccessForWidgets(inRequireSecurityOriginAccessForWidgets) |
| 947 | { } |
| 948 | |
| 949 | RenderLayer* rootLayer; |
| 950 | RenderObject* subtreePaintRoot; // Only paint descendants of this object. |
| 951 | LayoutRect paintDirtyRect; // Relative to rootLayer; |
| 952 | LayoutSize subpixelOffset; |
| 953 | OverlapTestRequestMap* overlapTestRequests; // May be null. |
| 954 | OptionSet<PaintBehavior> paintBehavior; |
| 955 | bool requireSecurityOriginAccessForWidgets; |
| 956 | bool clipToDirtyRect { true }; |
| 957 | EventRegionContext* eventRegionContext { nullptr }; |
| 958 | }; |
| 959 | |
| 960 | // Compute, cache and return clip rects computed with the given layer as the root. |
| 961 | Ref<ClipRects> updateClipRects(const ClipRectsContext&); |
| 962 | // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors |
| 963 | // (rather than computing them all from scratch up the parent chain). |
| 964 | void calculateClipRects(const ClipRectsContext&, ClipRects&) const; |
| 965 | ClipRects* clipRects(const ClipRectsContext&) const; |
| 966 | |
| 967 | void setAncestorChainHasSelfPaintingLayerDescendant(); |
| 968 | void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
| 969 | |
| 970 | void computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* = nullptr); |
| 971 | void computeRepaintRectsIncludingDescendants(); |
| 972 | void clearRepaintRects(); |
| 973 | |
| 974 | LayoutRect clipRectRelativeToAncestor(RenderLayer* ancestor, LayoutSize offsetFromAncestor, const LayoutRect& constrainingRect) const; |
| 975 | |
| 976 | void clipToRect(GraphicsContext&, const LayerPaintingInfo&, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius); |
| 977 | void restoreClip(GraphicsContext&, const LayerPaintingInfo&, const ClipRect&); |
| 978 | |
| 979 | bool shouldRepaintAfterLayout() const; |
| 980 | |
| 981 | void updateSelfPaintingLayer(); |
| 982 | |
| 983 | void updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle); |
| 984 | void updateScrollbarsAfterLayout(); |
| 985 | |
| 986 | // Returns true if the position changed. |
| 987 | bool updateLayerPosition(OptionSet<UpdateLayerPositionsFlag>* = nullptr); |
| 988 | |
| 989 | void updateLayerPositions(RenderGeometryMap* = nullptr, OptionSet<UpdateLayerPositionsFlag> = updateLayerPositionsDefaultFlags()); |
| 990 | |
| 991 | enum UpdateLayerPositionsAfterScrollFlag { |
| 992 | IsOverflowScroll = 1 << 0, |
| 993 | HasSeenViewportConstrainedAncestor = 1 << 1, |
| 994 | HasSeenAncestorWithOverflowClip = 1 << 2, |
| 995 | HasChangedAncestor = 1 << 3, |
| 996 | }; |
| 997 | void updateLayerPositionsAfterScroll(RenderGeometryMap*, OptionSet<UpdateLayerPositionsAfterScrollFlag> = { }); |
| 998 | |
| 999 | ScrollOffset clampScrollOffset(const ScrollOffset&) const; |
| 1000 | |
| 1001 | RenderLayer* (const RenderLayer* rootLayer, PaginationInclusionMode) const; |
| 1002 | |
| 1003 | LayoutPoint renderBoxLocation() const { return is<RenderBox>(renderer()) ? downcast<RenderBox>(renderer()).location() : LayoutPoint(); } |
| 1004 | |
| 1005 | bool setupFontSubpixelQuantization(GraphicsContext&, bool& didQuantizeFonts); |
| 1006 | |
| 1007 | Path computeClipPath(const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, WindRule&) const; |
| 1008 | |
| 1009 | bool setupClipPath(GraphicsContext&, const LayerPaintingInfo&, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); |
| 1010 | |
| 1011 | void ensureLayerFilters(); |
| 1012 | void clearLayerFilters(); |
| 1013 | |
| 1014 | RenderLayerFilters* filtersForPainting(GraphicsContext&, OptionSet<PaintLayerFlag>) const; |
| 1015 | GraphicsContext* setupFilters(GraphicsContext& destinationContext, LayerPaintingInfo&, OptionSet<PaintLayerFlag>, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); |
| 1016 | void applyFilters(GraphicsContext& originalContext, const LayerPaintingInfo&, const LayerFragments&); |
| 1017 | |
| 1018 | void paintLayer(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); |
| 1019 | void paintLayerWithEffects(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); |
| 1020 | |
| 1021 | void paintLayerContentsAndReflection(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); |
| 1022 | void paintLayerByApplyingTransform(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>, const LayoutSize& translationOffset = LayoutSize()); |
| 1023 | void paintLayerContents(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); |
| 1024 | void paintList(LayerList, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); |
| 1025 | |
| 1026 | void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>, bool shouldPaintContent, const LayoutSize& offsetFromRoot); |
| 1027 | void paintBackgroundForFragments(const LayerFragments&, GraphicsContext&, GraphicsContext& transparencyLayerContext, |
| 1028 | const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer); |
| 1029 | void paintForegroundForFragments(const LayerFragments&, GraphicsContext&, GraphicsContext& transparencyLayerContext, |
| 1030 | const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer); |
| 1031 | void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer); |
| 1032 | void paintOutlineForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer); |
| 1033 | void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&); |
| 1034 | void paintMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer); |
| 1035 | void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer); |
| 1036 | void paintTransformedLayerIntoFragments(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); |
| 1037 | void collectEventRegionForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&); |
| 1038 | |
| 1039 | RenderLayer* transparentPaintingAncestor(); |
| 1040 | void beginTransparencyLayers(GraphicsContext&, const LayerPaintingInfo&, const LayoutRect& dirtyRect); |
| 1041 | |
| 1042 | RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, |
| 1043 | const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform, |
| 1044 | const HitTestingTransformState* = nullptr, double* zOffset = nullptr); |
| 1045 | RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, |
| 1046 | const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr, |
| 1047 | const LayoutSize& translationOffset = LayoutSize()); |
| 1048 | RenderLayer* hitTestList(LayerList, RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&, |
| 1049 | const LayoutRect& hitTestRect, const HitTestLocation&, |
| 1050 | const HitTestingTransformState*, double* zOffsetForDescendants, double* zOffset, |
| 1051 | const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants); |
| 1052 | |
| 1053 | Ref<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer, |
| 1054 | const LayoutRect& hitTestRect, const HitTestLocation&, |
| 1055 | const HitTestingTransformState* containerTransformState, |
| 1056 | const LayoutSize& translationOffset = LayoutSize()) const; |
| 1057 | |
| 1058 | bool hitTestContents(const HitTestRequest&, HitTestResult&, const LayoutRect& layerBounds, const HitTestLocation&, HitTestFilter) const; |
| 1059 | bool hitTestContentsForFragments(const LayerFragments&, const HitTestRequest&, HitTestResult&, const HitTestLocation&, HitTestFilter, bool& insideClipRect) const; |
| 1060 | bool hitTestResizerInFragments(const LayerFragments&, const HitTestLocation&) const; |
| 1061 | RenderLayer* hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, |
| 1062 | const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr); |
| 1063 | |
| 1064 | bool listBackgroundIsKnownToBeOpaqueInRect(const LayerList&, const LayoutRect&) const; |
| 1065 | |
| 1066 | void computeScrollDimensions(); |
| 1067 | bool hasHorizontalOverflow() const; |
| 1068 | bool hasVerticalOverflow() const; |
| 1069 | bool hasScrollableHorizontalOverflow() const; |
| 1070 | bool hasScrollableVerticalOverflow() const; |
| 1071 | |
| 1072 | bool showsOverflowControls() const; |
| 1073 | |
| 1074 | bool shouldBeSelfPaintingLayer() const; |
| 1075 | |
| 1076 | int scrollOffset(ScrollbarOrientation) const override; |
| 1077 | |
| 1078 | // ScrollableArea interface |
| 1079 | void invalidateScrollbarRect(Scrollbar&, const IntRect&) override; |
| 1080 | void invalidateScrollCornerRect(const IntRect&) override; |
| 1081 | bool isActive() const override; |
| 1082 | bool isScrollCornerVisible() const override; |
| 1083 | IntRect scrollCornerRect() const override; |
| 1084 | IntRect convertFromScrollbarToContainingView(const Scrollbar&, const IntRect&) const override; |
| 1085 | IntRect convertFromContainingViewToScrollbar(const Scrollbar&, const IntRect&) const override; |
| 1086 | IntPoint convertFromScrollbarToContainingView(const Scrollbar&, const IntPoint&) const override; |
| 1087 | IntPoint convertFromContainingViewToScrollbar(const Scrollbar&, const IntPoint&) const override; |
| 1088 | int scrollSize(ScrollbarOrientation) const override; |
| 1089 | void setScrollOffset(const ScrollOffset&) override; |
| 1090 | ScrollingNodeID scrollingNodeID() const override; |
| 1091 | |
| 1092 | IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override; |
| 1093 | IntSize overhangAmount() const override; |
| 1094 | IntPoint lastKnownMousePosition() const override; |
| 1095 | bool isHandlingWheelEvent() const override; |
| 1096 | bool shouldSuspendScrollAnimations() const override; |
| 1097 | IntRect scrollableAreaBoundingBox(bool* isInsideFixed = nullptr) const override; |
| 1098 | bool isRubberBandInProgress() const override; |
| 1099 | bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override; |
| 1100 | #if ENABLE(CSS_SCROLL_SNAP) |
| 1101 | bool isScrollSnapInProgress() const override; |
| 1102 | #endif |
| 1103 | bool usesMockScrollAnimator() const override; |
| 1104 | void logMockScrollAnimatorMessage(const String&) const override; |
| 1105 | |
| 1106 | #if ENABLE(IOS_TOUCH_EVENTS) |
| 1107 | void registerAsTouchEventListenerForScrolling(); |
| 1108 | void unregisterAsTouchEventListenerForScrolling(); |
| 1109 | #endif |
| 1110 | |
| 1111 | // Rectangle encompassing the scroll corner and resizer rect. |
| 1112 | LayoutRect scrollCornerAndResizerRect() const; |
| 1113 | |
| 1114 | // NOTE: This should only be called by the overridden setScrollOffset from ScrollableArea. |
| 1115 | void scrollTo(const ScrollPosition&); |
| 1116 | void updateCompositingLayersAfterScroll(); |
| 1117 | |
| 1118 | IntSize scrollbarOffset(const Scrollbar&) const; |
| 1119 | |
| 1120 | void updateScrollableAreaSet(bool hasOverflow); |
| 1121 | |
| 1122 | bool allowsCurrentScroll() const; |
| 1123 | |
| 1124 | void dirtyAncestorChainVisibleDescendantStatus(); |
| 1125 | void setAncestorChainHasVisibleDescendant(); |
| 1126 | |
| 1127 | bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; } |
| 1128 | |
| 1129 | bool hasTransformedAncestor() const { return m_hasTransformedAncestor; } |
| 1130 | bool has3DTransformedAncestor() const { return m_has3DTransformedAncestor; } |
| 1131 | |
| 1132 | void dirty3DTransformedDescendantStatus(); |
| 1133 | // Both updates the status, and returns true if descendants of this have 3d. |
| 1134 | bool update3DTransformedDescendantStatus(); |
| 1135 | |
| 1136 | void createReflection(); |
| 1137 | void removeReflection(); |
| 1138 | |
| 1139 | RenderStyle createReflectionStyle(); |
| 1140 | bool paintingInsideReflection() const { return m_paintingInsideReflection; } |
| 1141 | void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; } |
| 1142 | |
| 1143 | void updateFiltersAfterStyleChange(); |
| 1144 | void updateFilterPaintingStrategy(); |
| 1145 | |
| 1146 | #if ENABLE(CSS_COMPOSITING) |
| 1147 | void updateAncestorChainHasBlendingDescendants(); |
| 1148 | void dirtyAncestorChainHasBlendingDescendants(); |
| 1149 | #endif |
| 1150 | |
| 1151 | Ref<ClipRects> parentClipRects(const ClipRectsContext&) const; |
| 1152 | ClipRect backgroundClipRect(const ClipRectsContext&) const; |
| 1153 | |
| 1154 | RenderLayer* enclosingTransformedAncestor() const; |
| 1155 | |
| 1156 | LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY) const; |
| 1157 | |
| 1158 | // Convert a point in absolute coords into layer coords, taking transforms into account |
| 1159 | LayoutPoint absoluteToContents(const LayoutPoint&) const; |
| 1160 | |
| 1161 | void positionOverflowControls(const IntSize&); |
| 1162 | void updateScrollCornerStyle(); |
| 1163 | void clearScrollCorner(); |
| 1164 | void updateResizerStyle(); |
| 1165 | void clearResizer(); |
| 1166 | |
| 1167 | void drawPlatformResizerImage(GraphicsContext&, const LayoutRect& resizerCornerRect); |
| 1168 | |
| 1169 | void (); |
| 1170 | |
| 1171 | void setHasCompositingDescendant(bool b) { m_hasCompositingDescendant = b; } |
| 1172 | |
| 1173 | void setIndirectCompositingReason(IndirectCompositingReason reason) { m_indirectCompositingReason = static_cast<unsigned>(reason); } |
| 1174 | bool mustCompositeForIndirectReasons() const { return m_indirectCompositingReason; } |
| 1175 | |
| 1176 | friend class RenderLayerBacking; |
| 1177 | friend class RenderLayerCompositor; |
| 1178 | friend class RenderLayerModelObject; |
| 1179 | |
| 1180 | LayoutUnit overflowTop() const; |
| 1181 | LayoutUnit overflowBottom() const; |
| 1182 | LayoutUnit overflowLeft() const; |
| 1183 | LayoutUnit overflowRight() const; |
| 1184 | |
| 1185 | IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const; |
| 1186 | IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const; |
| 1187 | |
| 1188 | LayoutUnit verticalScrollbarStart(int minX, int maxX) const; |
| 1189 | LayoutUnit horizontalScrollbarStart(int minX) const; |
| 1190 | |
| 1191 | bool overflowControlsIntersectRect(const IntRect& localRect) const; |
| 1192 | |
| 1193 | OptionSet<Compositing> m_compositingDirtyBits; |
| 1194 | |
| 1195 | const bool m_isRenderViewLayer : 1; |
| 1196 | const bool m_forcedStackingContext : 1; |
| 1197 | |
| 1198 | bool m_isNormalFlowOnly : 1; |
| 1199 | bool m_isCSSStackingContext : 1; |
| 1200 | bool m_isOpportunisticStackingContext : 1; |
| 1201 | |
| 1202 | bool m_zOrderListsDirty : 1; |
| 1203 | bool m_normalFlowListDirty: 1; |
| 1204 | bool m_hadNegativeZOrderList : 1; |
| 1205 | |
| 1206 | // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. |
| 1207 | bool m_inResizeMode : 1; |
| 1208 | |
| 1209 | bool m_scrollDimensionsDirty : 1; |
| 1210 | bool m_isSelfPaintingLayer : 1; |
| 1211 | |
| 1212 | // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to |
| 1213 | // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells). |
| 1214 | bool m_hasSelfPaintingLayerDescendant : 1; |
| 1215 | bool m_hasSelfPaintingLayerDescendantDirty : 1; |
| 1216 | |
| 1217 | bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether |
| 1218 | // we ended up painting this layer or any descendants (and therefore need to |
| 1219 | // blend). |
| 1220 | bool m_paintingInsideReflection : 1; // A state bit tracking if we are painting inside a replica. |
| 1221 | bool m_inOverflowRelayout : 1; |
| 1222 | unsigned m_repaintStatus : 2; // RepaintStatus |
| 1223 | |
| 1224 | bool m_visibleContentStatusDirty : 1; |
| 1225 | bool m_hasVisibleContent : 1; |
| 1226 | bool m_visibleDescendantStatusDirty : 1; |
| 1227 | bool m_hasVisibleDescendant : 1; |
| 1228 | bool m_registeredScrollableArea : 1; |
| 1229 | bool m_isFixedIntersectingViewport : 1; |
| 1230 | |
| 1231 | bool m_3DTransformedDescendantStatusDirty : 1; |
| 1232 | bool m_has3DTransformedDescendant : 1; // Set on a stacking context layer that has 3D descendants anywhere |
| 1233 | // in a preserves3D hierarchy. Hint to do 3D-aware hit testing. |
| 1234 | bool m_hasCompositingDescendant : 1; // In the z-order tree. |
| 1235 | |
| 1236 | bool m_hasCompositedScrollingAncestor : 1; // In the layer-order tree. |
| 1237 | |
| 1238 | bool m_hasTransformedAncestor : 1; |
| 1239 | bool m_has3DTransformedAncestor : 1; |
| 1240 | |
| 1241 | unsigned m_indirectCompositingReason : 3; |
| 1242 | unsigned m_viewportConstrainedNotCompositedReason : 2; |
| 1243 | |
| 1244 | #if PLATFORM(IOS_FAMILY) |
| 1245 | #if ENABLE(IOS_TOUCH_EVENTS) |
| 1246 | bool m_registeredAsTouchEventListenerForScrolling : 1; |
| 1247 | #endif |
| 1248 | bool m_adjustForIOSCaretWhenScrolling : 1; |
| 1249 | #endif |
| 1250 | |
| 1251 | bool m_requiresScrollPositionReconciliation : 1; |
| 1252 | bool m_containsDirtyOverlayScrollbars : 1; |
| 1253 | bool m_updatingMarqueePosition : 1; |
| 1254 | |
| 1255 | #if !ASSERT_DISABLED |
| 1256 | bool m_layerListMutationAllowed : 1; |
| 1257 | #endif |
| 1258 | |
| 1259 | #if ENABLE(CSS_COMPOSITING) |
| 1260 | unsigned m_blendMode : 5; |
| 1261 | bool m_hasNotIsolatedCompositedBlendingDescendants : 1; |
| 1262 | bool m_hasNotIsolatedBlendingDescendants : 1; |
| 1263 | bool m_hasNotIsolatedBlendingDescendantsStatusDirty : 1; |
| 1264 | #endif |
| 1265 | |
| 1266 | RenderLayerModelObject& m_renderer; |
| 1267 | |
| 1268 | RenderLayer* m_parent { nullptr }; |
| 1269 | RenderLayer* m_previous { nullptr }; |
| 1270 | RenderLayer* m_next { nullptr }; |
| 1271 | RenderLayer* m_first { nullptr }; |
| 1272 | RenderLayer* m_last { nullptr }; |
| 1273 | |
| 1274 | WeakPtr<RenderLayer> m_backingProviderLayer; |
| 1275 | |
| 1276 | // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the |
| 1277 | // descendant layers within the stacking context that have z-indices of 0 or greater |
| 1278 | // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative |
| 1279 | // z-indices. |
| 1280 | std::unique_ptr<Vector<RenderLayer*>> m_posZOrderList; |
| 1281 | std::unique_ptr<Vector<RenderLayer*>> m_negZOrderList; |
| 1282 | |
| 1283 | // This list contains child layers that cannot create stacking contexts and appear in normal flow order. |
| 1284 | std::unique_ptr<Vector<RenderLayer*>> m_normalFlowList; |
| 1285 | |
| 1286 | // Our current relative position offset. |
| 1287 | LayoutSize m_offsetForInFlowPosition; |
| 1288 | |
| 1289 | // Our (x,y) coordinates are in our parent layer's coordinate space. |
| 1290 | LayoutPoint m_topLeft; |
| 1291 | |
| 1292 | // The layer's width/height |
| 1293 | IntSize m_layerSize; |
| 1294 | |
| 1295 | ScrollPosition m_scrollPosition; |
| 1296 | Optional<ScrollPosition> m_postLayoutScrollPosition; |
| 1297 | |
| 1298 | // The width/height of our scrolled area. |
| 1299 | IntSize m_scrollSize; |
| 1300 | |
| 1301 | // For layers with overflow, we have a pair of scrollbars. |
| 1302 | RefPtr<Scrollbar> m_hBar; |
| 1303 | RefPtr<Scrollbar> m_vBar; |
| 1304 | |
| 1305 | std::unique_ptr<ClipRectsCache> m_clipRectsCache; |
| 1306 | |
| 1307 | IntPoint m_cachedOverlayScrollbarOffset; |
| 1308 | |
| 1309 | std::unique_ptr<RenderMarquee> m_marquee; // Used for <marquee>. |
| 1310 | |
| 1311 | // Cached normal flow values for absolute positioned elements with static left/top values. |
| 1312 | LayoutUnit m_staticInlinePosition; |
| 1313 | LayoutUnit m_staticBlockPosition; |
| 1314 | |
| 1315 | std::unique_ptr<TransformationMatrix> m_transform; |
| 1316 | |
| 1317 | // May ultimately be extended to many replicas (with their own paint order). |
| 1318 | RenderPtr<RenderReplica> m_reflection; |
| 1319 | |
| 1320 | // Renderers to hold our custom scroll corner and resizer. |
| 1321 | RenderPtr<RenderScrollbarPart> m_scrollCorner; |
| 1322 | RenderPtr<RenderScrollbarPart> m_resizer; |
| 1323 | |
| 1324 | // Pointer to the enclosing RenderLayer that caused us to be paginated. It is 0 if we are not paginated. |
| 1325 | WeakPtr<RenderLayer> ; |
| 1326 | |
| 1327 | IntRect m_blockSelectionGapsBounds; |
| 1328 | |
| 1329 | std::unique_ptr<RenderLayerFilters> m_filters; |
| 1330 | std::unique_ptr<RenderLayerBacking> m_backing; |
| 1331 | |
| 1332 | PaintFrequencyTracker m_paintFrequencyTracker; |
| 1333 | }; |
| 1334 | |
| 1335 | inline void RenderLayer::clearZOrderLists() |
| 1336 | { |
| 1337 | ASSERT(!isStackingContext()); |
| 1338 | ASSERT(layerListMutationAllowed()); |
| 1339 | |
| 1340 | m_posZOrderList = nullptr; |
| 1341 | m_negZOrderList = nullptr; |
| 1342 | } |
| 1343 | |
| 1344 | inline void RenderLayer::updateZOrderLists() |
| 1345 | { |
| 1346 | if (!m_zOrderListsDirty) |
| 1347 | return; |
| 1348 | |
| 1349 | if (!isStackingContext()) { |
| 1350 | clearZOrderLists(); |
| 1351 | m_zOrderListsDirty = false; |
| 1352 | return; |
| 1353 | } |
| 1354 | |
| 1355 | rebuildZOrderLists(); |
| 1356 | } |
| 1357 | |
| 1358 | inline RenderLayer* RenderLayer::paintOrderParent() const |
| 1359 | { |
| 1360 | return m_isNormalFlowOnly ? m_parent : stackingContext(); |
| 1361 | } |
| 1362 | |
| 1363 | #if !ASSERT_DISABLED |
| 1364 | class LayerListMutationDetector { |
| 1365 | public: |
| 1366 | LayerListMutationDetector(RenderLayer& layer) |
| 1367 | : m_layer(layer) |
| 1368 | , m_previousMutationAllowedState(layer.layerListMutationAllowed()) |
| 1369 | { |
| 1370 | m_layer.setLayerListMutationAllowed(false); |
| 1371 | } |
| 1372 | |
| 1373 | ~LayerListMutationDetector() |
| 1374 | { |
| 1375 | m_layer.setLayerListMutationAllowed(m_previousMutationAllowedState); |
| 1376 | } |
| 1377 | |
| 1378 | private: |
| 1379 | RenderLayer& m_layer; |
| 1380 | bool m_previousMutationAllowedState; |
| 1381 | }; |
| 1382 | #endif |
| 1383 | |
| 1384 | void makeMatrixRenderable(TransformationMatrix&, bool has3DRendering); |
| 1385 | |
| 1386 | bool compositedWithOwnBackingStore(const RenderLayer&); |
| 1387 | |
| 1388 | WTF::TextStream& operator<<(WTF::TextStream&, ClipRectsType); |
| 1389 | WTF::TextStream& operator<<(WTF::TextStream&, const RenderLayer&); |
| 1390 | WTF::TextStream& operator<<(WTF::TextStream&, const RenderLayer::ClipRectsContext&); |
| 1391 | WTF::TextStream& operator<<(WTF::TextStream&, IndirectCompositingReason); |
| 1392 | |
| 1393 | } // namespace WebCore |
| 1394 | |
| 1395 | #if ENABLE(TREE_DEBUGGING) |
| 1396 | // Outside the WebCore namespace for ease of invocation from lldb. |
| 1397 | void showLayerTree(const WebCore::RenderLayer*); |
| 1398 | void showPaintOrderTree(const WebCore::RenderLayer*); |
| 1399 | void showLayerTree(const WebCore::RenderObject*); |
| 1400 | #endif |
| 1401 | |