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 | |