1 | /* |
2 | * Copyright (C) 2009, 2013 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include "ChromeClient.h" |
29 | #include "GraphicsLayerClient.h" |
30 | #include "GraphicsLayerUpdater.h" |
31 | #include "RenderLayer.h" |
32 | #include <wtf/HashMap.h> |
33 | #include <wtf/OptionSet.h> |
34 | |
35 | namespace WebCore { |
36 | |
37 | class FixedPositionViewportConstraints; |
38 | class GraphicsLayer; |
39 | class GraphicsLayerUpdater; |
40 | class LayerOverlapMap; |
41 | class RenderEmbeddedObject; |
42 | class RenderVideo; |
43 | class RenderWidget; |
44 | class ScrollingCoordinator; |
45 | class StickyPositionViewportConstraints; |
46 | class TiledBacking; |
47 | |
48 | typedef unsigned LayerTreeFlags; |
49 | |
50 | enum class CompositingUpdateType { |
51 | AfterStyleChange, |
52 | AfterLayout, |
53 | OnScroll, |
54 | OnCompositedScroll |
55 | }; |
56 | |
57 | enum class CompositingReason { |
58 | Transform3D = 1 << 0, |
59 | Video = 1 << 1, |
60 | Canvas = 1 << 2, |
61 | Plugin = 1 << 3, |
62 | IFrame = 1 << 4, |
63 | BackfaceVisibilityHidden = 1 << 5, |
64 | ClipsCompositingDescendants = 1 << 6, |
65 | Animation = 1 << 7, |
66 | Filters = 1 << 8, |
67 | PositionFixed = 1 << 9, |
68 | PositionSticky = 1 << 10, |
69 | OverflowScrolling = 1 << 11, |
70 | Stacking = 1 << 12, |
71 | Overlap = 1 << 13, |
72 | OverflowScrollPositioning = 1 << 14, |
73 | NegativeZIndexChildren = 1 << 15, |
74 | TransformWithCompositedDescendants = 1 << 16, |
75 | OpacityWithCompositedDescendants = 1 << 17, |
76 | MaskWithCompositedDescendants = 1 << 18, |
77 | ReflectionWithCompositedDescendants = 1 << 19, |
78 | FilterWithCompositedDescendants = 1 << 20, |
79 | BlendingWithCompositedDescendants = 1 << 21, |
80 | Perspective = 1 << 22, |
81 | Preserve3D = 1 << 23, |
82 | WillChange = 1 << 24, |
83 | Root = 1 << 25, |
84 | IsolatesCompositedBlendingDescendants = 1 << 26, |
85 | EmbeddedView = 1 << 27, |
86 | }; |
87 | |
88 | enum class ScrollCoordinationRole { |
89 | ViewportConstrained = 1 << 0, |
90 | Scrolling = 1 << 1, |
91 | FrameHosting = 1 << 2, |
92 | Positioning = 1 << 3, |
93 | }; |
94 | |
95 | #if PLATFORM(IOS_FAMILY) |
96 | class LegacyWebKitScrollingLayerCoordinator { |
97 | public: |
98 | LegacyWebKitScrollingLayerCoordinator(ChromeClient& chromeClient, bool coordinateViewportConstrainedLayers) |
99 | : m_chromeClient(chromeClient) |
100 | , m_coordinateViewportConstrainedLayers(coordinateViewportConstrainedLayers) |
101 | { |
102 | } |
103 | |
104 | void registerAllViewportConstrainedLayers(RenderLayerCompositor&); |
105 | void unregisterAllViewportConstrainedLayers(); |
106 | |
107 | void registerAllScrollingLayers(); |
108 | void registerScrollingLayersNeedingUpdate(); |
109 | void unregisterAllScrollingLayers(); |
110 | |
111 | void addScrollingLayer(RenderLayer&); |
112 | void removeScrollingLayer(RenderLayer&, RenderLayerBacking&); |
113 | |
114 | void addViewportConstrainedLayer(RenderLayer&); |
115 | void removeViewportConstrainedLayer(RenderLayer&); |
116 | |
117 | void didChangePlatformLayerForLayer(RenderLayer&); |
118 | |
119 | void removeLayer(RenderLayer&); |
120 | |
121 | private: |
122 | void updateScrollingLayer(RenderLayer&); |
123 | |
124 | ChromeClient& m_chromeClient; |
125 | |
126 | HashSet<RenderLayer*> m_scrollingLayers; |
127 | HashSet<RenderLayer*> m_viewportConstrainedLayers; |
128 | |
129 | HashSet<RenderLayer*> m_scrollingLayersNeedingUpdate; |
130 | const bool m_coordinateViewportConstrainedLayers; |
131 | }; |
132 | #endif |
133 | |
134 | // RenderLayerCompositor manages the hierarchy of |
135 | // composited RenderLayers. It determines which RenderLayers |
136 | // become compositing, and creates and maintains a hierarchy of |
137 | // GraphicsLayers based on the RenderLayer painting order. |
138 | // |
139 | // There is one RenderLayerCompositor per RenderView. |
140 | |
141 | class RenderLayerCompositor final : public GraphicsLayerClient, public GraphicsLayerUpdaterClient { |
142 | WTF_MAKE_FAST_ALLOCATED; |
143 | friend class LegacyWebKitScrollingLayerCoordinator; |
144 | public: |
145 | explicit RenderLayerCompositor(RenderView&); |
146 | virtual ~RenderLayerCompositor(); |
147 | |
148 | // Return true if this RenderView is in "compositing mode" (i.e. has one or more |
149 | // composited RenderLayers) |
150 | bool usesCompositing() const { return m_compositing; } |
151 | // This will make a compositing layer at the root automatically, and hook up to |
152 | // the native view/window system. |
153 | void enableCompositingMode(bool enable = true); |
154 | |
155 | bool inForcedCompositingMode() const { return m_forceCompositingMode; } |
156 | |
157 | // True when some content element other than the root is composited. |
158 | bool hasContentCompositingLayers() const { return m_contentLayersCount; } |
159 | |
160 | // Returns true if the accelerated compositing is enabled |
161 | bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; } |
162 | |
163 | bool canRender3DTransforms() const; |
164 | |
165 | void willRecalcStyle(); |
166 | |
167 | // Returns true if the composited layers were actually updated. |
168 | bool didRecalcStyleWithNoPendingLayout(); |
169 | |
170 | // GraphicsLayers buffer state, which gets pushed to the underlying platform layers |
171 | // at specific times. |
172 | void scheduleLayerFlush(bool canThrottle = false); |
173 | void flushPendingLayerChanges(bool isFlushRoot = true); |
174 | |
175 | // Called when the GraphicsLayer for the given RenderLayer has flushed changes inside of flushPendingLayerChanges(). |
176 | void didChangePlatformLayerForLayer(RenderLayer&, const GraphicsLayer*); |
177 | |
178 | // Called when something outside WebKit affects the visible rect (e.g. delegated scrolling). Might schedule a layer flush. |
179 | void didChangeVisibleRect(); |
180 | |
181 | // Rebuild the tree of compositing layers |
182 | bool updateCompositingLayers(CompositingUpdateType, RenderLayer* updateRoot = nullptr); |
183 | // This is only used when state changes and we do not exepect a style update or layout to happen soon (e.g. when |
184 | // we discover that an iframe is overlapped during painting). |
185 | void scheduleCompositingLayerUpdate(); |
186 | // This is used to cancel any pending update timers when the document goes into page cache. |
187 | void cancelCompositingLayerUpdate(); |
188 | |
189 | // Update the compositing state of the given layer. Returns true if that state changed. |
190 | enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater }; |
191 | enum class LayoutUpToDate { |
192 | Yes, No |
193 | }; |
194 | |
195 | struct RequiresCompositingData { |
196 | LayoutUpToDate layoutUpToDate { LayoutUpToDate::Yes }; |
197 | RenderLayer::ViewportConstrainedNotCompositedReason nonCompositedForPositionReason { RenderLayer::NoNotCompositedReason }; |
198 | bool reevaluateAfterLayout { false }; |
199 | }; |
200 | |
201 | bool updateLayerCompositingState(RenderLayer&, RequiresCompositingData&, CompositingChangeRepaint = CompositingChangeRepaintNow); |
202 | |
203 | // Whether layer's backing needs a graphics layer to do clipping by an ancestor (non-stacking-context parent with overflow). |
204 | bool clippedByAncestor(RenderLayer&) const; |
205 | // Whether layer's backing needs a graphics layer to clip z-order children of the given layer. |
206 | static bool clipsCompositingDescendants(const RenderLayer&); |
207 | |
208 | // Whether the given layer needs an extra 'contents' layer. |
209 | bool needsContentsCompositingLayer(const RenderLayer&) const; |
210 | |
211 | bool fixedLayerIntersectsViewport(const RenderLayer&) const; |
212 | |
213 | bool supportsFixedRootBackgroundCompositing() const; |
214 | bool needsFixedRootBackgroundLayer(const RenderLayer&) const; |
215 | GraphicsLayer* fixedRootBackgroundLayer() const; |
216 | |
217 | void rootOrBodyStyleChanged(RenderElement&, const RenderStyle* oldStyle); |
218 | |
219 | // Called after the view transparency, or the document or base background color change. |
220 | void rootBackgroundColorOrTransparencyChanged(); |
221 | |
222 | // Repaint the appropriate layers when the given RenderLayer starts or stops being composited. |
223 | void repaintOnCompositingChange(RenderLayer&); |
224 | |
225 | void repaintInCompositedAncestor(RenderLayer&, const LayoutRect&); |
226 | |
227 | // Notify us that a layer has been added or removed |
228 | void layerWasAdded(RenderLayer& parent, RenderLayer& child); |
229 | void layerWillBeRemoved(RenderLayer& parent, RenderLayer& child); |
230 | |
231 | void layerStyleChanged(StyleDifference, RenderLayer&, const RenderStyle* oldStyle); |
232 | |
233 | static bool canCompositeClipPath(const RenderLayer&); |
234 | |
235 | // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context |
236 | RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer&) const; |
237 | |
238 | // Repaint all composited layers. |
239 | void repaintCompositedLayers(); |
240 | |
241 | // Returns true if the given layer needs it own backing store. |
242 | bool requiresOwnBackingStore(const RenderLayer&, const RenderLayer* compositingAncestorLayer, const LayoutRect& layerCompositedBoundsInAncestor, const LayoutRect& ancestorCompositedBounds) const; |
243 | |
244 | WEBCORE_EXPORT RenderLayer& rootRenderLayer() const; |
245 | GraphicsLayer* rootGraphicsLayer() const; |
246 | |
247 | GraphicsLayer* scrollContainerLayer() const { return m_scrollContainerLayer.get(); } |
248 | GraphicsLayer* scrolledContentsLayer() const { return m_scrolledContentsLayer.get(); } |
249 | GraphicsLayer* clipLayer() const { return m_clipLayer.get(); } |
250 | GraphicsLayer* rootContentsLayer() const { return m_rootContentsLayer.get(); } |
251 | |
252 | GraphicsLayer* layerForClipping() const { return m_clipLayer ? m_clipLayer.get() : m_scrollContainerLayer.get(); } |
253 | |
254 | #if ENABLE(RUBBER_BANDING) |
255 | GraphicsLayer* headerLayer() const { return m_layerForHeader.get(); } |
256 | GraphicsLayer* footerLayer() const { return m_layerForFooter.get(); } |
257 | #endif |
258 | |
259 | enum RootLayerAttachment { |
260 | RootLayerUnattached, |
261 | RootLayerAttachedViaChromeClient, |
262 | RootLayerAttachedViaEnclosingFrame |
263 | }; |
264 | |
265 | RootLayerAttachment rootLayerAttachment() const { return m_rootLayerAttachment; } |
266 | void updateRootLayerAttachment(); |
267 | void updateRootLayerPosition(); |
268 | |
269 | void setIsInWindow(bool); |
270 | |
271 | void clearBackingForAllLayers(); |
272 | |
273 | void layerBecameComposited(const RenderLayer&); |
274 | void layerBecameNonComposited(const RenderLayer&); |
275 | |
276 | #if ENABLE(VIDEO) |
277 | // Use by RenderVideo to ask if it should try to use accelerated compositing. |
278 | bool canAccelerateVideoRendering(RenderVideo&) const; |
279 | #endif |
280 | |
281 | // Walk the tree looking for layers with 3d transforms. Useful in case you need |
282 | // to know if there is non-affine content, e.g. for drawing into an image. |
283 | bool has3DContent() const; |
284 | |
285 | static RenderLayerCompositor* frameContentsCompositor(RenderWidget&); |
286 | // Return true if the layers changed. |
287 | bool parentFrameContentLayers(RenderWidget&); |
288 | |
289 | // Update the geometry of the layers used for clipping and scrolling in frames. |
290 | void frameViewDidChangeLocation(const IntPoint& contentsOffset); |
291 | void frameViewDidChangeSize(); |
292 | void frameViewDidScroll(); |
293 | void frameViewDidAddOrRemoveScrollbars(); |
294 | void frameViewDidLayout(); |
295 | void rootLayerConfigurationChanged(); |
296 | |
297 | String layerTreeAsText(LayerTreeFlags); |
298 | |
299 | float deviceScaleFactor() const override; |
300 | float contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const override; |
301 | float pageScaleFactor() const override; |
302 | float zoomedOutPageScaleFactor() const override; |
303 | void didChangePlatformLayerForLayer(const GraphicsLayer*) override { } |
304 | void notifyFlushBeforeDisplayRefresh(const GraphicsLayer*) override; |
305 | |
306 | void layerTiledBackingUsageChanged(const GraphicsLayer*, bool /*usingTiledBacking*/); |
307 | |
308 | bool acceleratedDrawingEnabled() const { return m_acceleratedDrawingEnabled; } |
309 | bool displayListDrawingEnabled() const { return m_displayListDrawingEnabled; } |
310 | |
311 | void deviceOrPageScaleFactorChanged(); |
312 | |
313 | void windowScreenDidChange(PlatformDisplayID); |
314 | |
315 | GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); } |
316 | GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); } |
317 | GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); } |
318 | #if ENABLE(RUBBER_BANDING) |
319 | GraphicsLayer* layerForOverhangAreas() const { return m_layerForOverhangAreas.get(); } |
320 | GraphicsLayer* layerForContentShadow() const { return m_contentShadowLayer.get(); } |
321 | |
322 | GraphicsLayer* updateLayerForTopOverhangArea(bool wantsLayer); |
323 | GraphicsLayer* updateLayerForBottomOverhangArea(bool wantsLayer); |
324 | GraphicsLayer* updateLayerForHeader(bool wantsLayer); |
325 | GraphicsLayer* updateLayerForFooter(bool wantsLayer); |
326 | #endif |
327 | |
328 | // FIXME: make the coordinated/async terminology consistent. |
329 | bool isViewportConstrainedFixedOrStickyLayer(const RenderLayer&) const; |
330 | bool useCoordinatedScrollingForLayer(const RenderLayer&) const; |
331 | ScrollPositioningBehavior computeCoordinatedPositioningForLayer(const RenderLayer&) const; |
332 | bool isLayerForIFrameWithScrollCoordinatedContents(const RenderLayer&) const; |
333 | |
334 | ScrollableArea* scrollableAreaForScrollLayerID(ScrollingNodeID) const; |
335 | |
336 | void removeFromScrollCoordinatedLayers(RenderLayer&); |
337 | |
338 | void willRemoveScrollingLayerWithBacking(RenderLayer&, RenderLayerBacking&); |
339 | void didAddScrollingLayer(RenderLayer&); |
340 | |
341 | void resetTrackedRepaintRects(); |
342 | void setTracksRepaints(bool tracksRepaints) { m_isTrackingRepaints = tracksRepaints; } |
343 | |
344 | bool viewHasTransparentBackground(Color* backgroundColor = nullptr) const; |
345 | |
346 | bool hasNonMainLayersWithTiledBacking() const { return m_layersWithTiledBackingCount; } |
347 | |
348 | OptionSet<CompositingReason> reasonsForCompositing(const RenderLayer&) const; |
349 | |
350 | void setLayerFlushThrottlingEnabled(bool); |
351 | void disableLayerFlushThrottlingTemporarilyForInteraction(); |
352 | |
353 | void didPaintBacking(RenderLayerBacking*); |
354 | |
355 | const Color& rootExtendedBackgroundColor() const { return m_rootExtendedBackgroundColor; } |
356 | |
357 | void updateRootContentLayerClipping(); |
358 | |
359 | #if ENABLE(CSS_SCROLL_SNAP) |
360 | void updateScrollSnapPropertiesWithFrameView(const FrameView&) const; |
361 | #endif |
362 | |
363 | // For testing. |
364 | void startTrackingLayerFlushes() { m_layerFlushCount = 0; } |
365 | unsigned layerFlushCount() const { return m_layerFlushCount; } |
366 | |
367 | void startTrackingCompositingUpdates() { m_compositingUpdateCount = 0; } |
368 | unsigned compositingUpdateCount() const { return m_compositingUpdateCount; } |
369 | |
370 | private: |
371 | class BackingSharingState; |
372 | struct CompositingState; |
373 | struct OverlapExtent; |
374 | |
375 | // Returns true if the policy changed. |
376 | bool updateCompositingPolicy(); |
377 | |
378 | // GraphicsLayerClient implementation |
379 | void notifyFlushRequired(const GraphicsLayer*) override; |
380 | void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect&, GraphicsLayerPaintBehavior) override; |
381 | void customPositionForVisibleRectComputation(const GraphicsLayer*, FloatPoint&) const override; |
382 | bool isTrackingRepaints() const override { return m_isTrackingRepaints; } |
383 | |
384 | // GraphicsLayerUpdaterClient implementation |
385 | void (GraphicsLayerUpdater&) override; |
386 | |
387 | // Copy the accelerated compositing related flags from Settings |
388 | void cacheAcceleratedCompositingFlags(); |
389 | void cacheAcceleratedCompositingFlagsAfterLayout(); |
390 | |
391 | // Whether the given RL needs a compositing layer. |
392 | bool needsToBeComposited(const RenderLayer&, RequiresCompositingData&) const; |
393 | // Whether the layer has an intrinsic need for compositing layer. |
394 | bool requiresCompositingLayer(const RenderLayer&, RequiresCompositingData&) const; |
395 | // Whether the layer could ever be composited. |
396 | bool canBeComposited(const RenderLayer&) const; |
397 | bool needsCompositingUpdateForStyleChangeOnNonCompositedLayer(RenderLayer&, const RenderStyle* oldStyle) const; |
398 | |
399 | // Make or destroy the backing for this layer; returns true if backing changed. |
400 | enum class BackingRequired { No, Yes, Unknown }; |
401 | bool updateBacking(RenderLayer&, RequiresCompositingData&, CompositingChangeRepaint shouldRepaint, BackingRequired = BackingRequired::Unknown); |
402 | |
403 | void clearBackingForLayerIncludingDescendants(RenderLayer&); |
404 | |
405 | // Repaint this and its child layers. |
406 | void recursiveRepaintLayer(RenderLayer&); |
407 | |
408 | void computeExtent(const LayerOverlapMap&, const RenderLayer&, OverlapExtent&) const; |
409 | void addToOverlapMap(LayerOverlapMap&, const RenderLayer&, OverlapExtent&) const; |
410 | void addDescendantsToOverlapMapRecursive(LayerOverlapMap&, const RenderLayer&, const RenderLayer* ancestorLayer = nullptr) const; |
411 | void updateOverlapMap(LayerOverlapMap&, const RenderLayer&, OverlapExtent&, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap = false) const; |
412 | |
413 | void updateCompositingLayersTimerFired(); |
414 | |
415 | void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer&, LayerOverlapMap&, CompositingState&, BackingSharingState&, bool& descendantHas3DTransform); |
416 | void traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer&, LayerOverlapMap&, CompositingState&, BackingSharingState&, bool& descendantHas3DTransform); |
417 | |
418 | enum class UpdateLevel { |
419 | AllDescendants = 1 << 0, |
420 | CompositedChildren = 1 << 1, |
421 | }; |
422 | // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer. |
423 | void updateBackingAndHierarchy(RenderLayer&, Vector<Ref<GraphicsLayer>>& childGraphicsLayersOfEnclosingLayer, struct ScrollingTreeState&, OptionSet<UpdateLevel> = { }, int depth = 0); |
424 | |
425 | bool layerHas3DContent(const RenderLayer&) const; |
426 | bool isRunningTransformAnimation(RenderLayerModelObject&) const; |
427 | |
428 | void appendDocumentOverlayLayers(Vector<Ref<GraphicsLayer>>&); |
429 | |
430 | bool needsCompositingForContentOrOverlays() const; |
431 | |
432 | void ensureRootLayer(); |
433 | void destroyRootLayer(); |
434 | |
435 | void attachRootLayer(RootLayerAttachment); |
436 | void detachRootLayer(); |
437 | |
438 | void rootLayerAttachmentChanged(); |
439 | |
440 | void updateOverflowControlsLayers(); |
441 | |
442 | void updateScrollLayerPosition(); |
443 | void updateScrollLayerClipping(); |
444 | |
445 | FloatPoint positionForClipLayer() const; |
446 | |
447 | void notifyIFramesOfCompositingChange(); |
448 | |
449 | #if PLATFORM(IOS_FAMILY) |
450 | void updateScrollCoordinatedLayersAfterFlushIncludingSubframes(); |
451 | void updateScrollCoordinatedLayersAfterFlush(); |
452 | #endif |
453 | |
454 | FloatRect visibleRectForLayerFlushing() const; |
455 | |
456 | Page& page() const; |
457 | |
458 | GraphicsLayerFactory* graphicsLayerFactory() const; |
459 | ScrollingCoordinator* scrollingCoordinator() const; |
460 | |
461 | #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) |
462 | RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const override; |
463 | #endif |
464 | |
465 | // Non layout-dependent |
466 | bool requiresCompositingForAnimation(RenderLayerModelObject&) const; |
467 | bool requiresCompositingForTransform(RenderLayerModelObject&) const; |
468 | bool requiresCompositingForBackfaceVisibility(RenderLayerModelObject&) const; |
469 | bool requiresCompositingForVideo(RenderLayerModelObject&) const; |
470 | bool requiresCompositingForCanvas(RenderLayerModelObject&) const; |
471 | bool requiresCompositingForFilters(RenderLayerModelObject&) const; |
472 | bool requiresCompositingForWillChange(RenderLayerModelObject&) const; |
473 | |
474 | // Layout-dependent |
475 | bool requiresCompositingForPlugin(RenderLayerModelObject&, RequiresCompositingData&) const; |
476 | bool requiresCompositingForFrame(RenderLayerModelObject&, RequiresCompositingData&) const; |
477 | bool requiresCompositingForScrollableFrame(RequiresCompositingData&) const; |
478 | bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RequiresCompositingData&) const; |
479 | bool requiresCompositingForOverflowScrolling(const RenderLayer&, RequiresCompositingData&) const; |
480 | bool requiresCompositingForEditableImage(RenderLayerModelObject&) const; |
481 | bool requiresCompositingForIndirectReason(const RenderLayer&, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason&) const; |
482 | |
483 | static bool layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer&, const RenderLayer& compositedAncestor); |
484 | |
485 | static bool styleChangeMayAffectIndirectCompositingReasons(const RenderStyle& oldStyle, const RenderStyle& newStyle); |
486 | |
487 | enum class ScrollingNodeChangeFlags { |
488 | Layer = 1 << 0, |
489 | LayerGeometry = 1 << 1, |
490 | }; |
491 | |
492 | ScrollingNodeID attachScrollingNode(RenderLayer&, ScrollingNodeType, struct ScrollingTreeState&); |
493 | |
494 | // Returns the ScrollingNodeID which acts as the parent for children. |
495 | ScrollingNodeID updateScrollCoordinationForLayer(RenderLayer&, struct ScrollingTreeState&, OptionSet<ScrollCoordinationRole>, OptionSet<ScrollingNodeChangeFlags>); |
496 | |
497 | // These return the ScrollingNodeID which acts as the parent for children. |
498 | ScrollingNodeID updateScrollingNodeForViewportConstrainedRole(RenderLayer&, struct ScrollingTreeState&, OptionSet<ScrollingNodeChangeFlags>); |
499 | ScrollingNodeID updateScrollingNodeForScrollingRole(RenderLayer&, struct ScrollingTreeState&, OptionSet<ScrollingNodeChangeFlags>); |
500 | ScrollingNodeID updateScrollingNodeForFrameHostingRole(RenderLayer&, struct ScrollingTreeState&, OptionSet<ScrollingNodeChangeFlags>); |
501 | ScrollingNodeID updateScrollingNodeForPositioningRole(RenderLayer&, struct ScrollingTreeState&, OptionSet<ScrollingNodeChangeFlags>); |
502 | |
503 | void updateScrollingNodeLayers(ScrollingNodeID, RenderLayer&, ScrollingCoordinator&); |
504 | |
505 | void detachScrollCoordinatedLayer(RenderLayer&, OptionSet<ScrollCoordinationRole>); |
506 | void detachScrollCoordinatedLayerWithRole(RenderLayer&, ScrollingCoordinator&, ScrollCoordinationRole); |
507 | |
508 | FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer&) const; |
509 | StickyPositionViewportConstraints computeStickyViewportConstraints(RenderLayer&) const; |
510 | |
511 | LayoutRect rootParentRelativeScrollableRect() const; |
512 | LayoutRect parentRelativeScrollableRect(const RenderLayer&, const RenderLayer* ancestorLayer) const; |
513 | |
514 | bool requiresScrollLayer(RootLayerAttachment) const; |
515 | bool requiresHorizontalScrollbarLayer() const; |
516 | bool requiresVerticalScrollbarLayer() const; |
517 | bool requiresScrollCornerLayer() const; |
518 | #if ENABLE(RUBBER_BANDING) |
519 | bool requiresOverhangAreasLayer() const; |
520 | bool requiresContentShadowLayer() const; |
521 | #endif |
522 | |
523 | // True if the FrameView uses a ScrollingCoordinator. |
524 | bool hasCoordinatedScrolling() const; |
525 | |
526 | // FIXME: make the coordinated/async terminology consistent. |
527 | bool isAsyncScrollableStickyLayer(const RenderLayer&, const RenderLayer** enclosingAcceleratedOverflowLayer = nullptr) const; |
528 | |
529 | bool shouldCompositeOverflowControls() const; |
530 | |
531 | bool isThrottlingLayerFlushes() const; |
532 | void startInitialLayerFlushTimerIfNeeded(); |
533 | void startLayerFlushTimerIfNeeded(); |
534 | void layerFlushTimerFired(); |
535 | |
536 | #if !LOG_DISABLED |
537 | const char* logReasonsForCompositing(const RenderLayer&); |
538 | void logLayerInfo(const RenderLayer&, const char*, int depth); |
539 | #endif |
540 | |
541 | bool documentUsesTiledBacking() const; |
542 | bool isMainFrameCompositor() const; |
543 | |
544 | private: |
545 | RenderView& m_renderView; |
546 | Timer m_updateCompositingLayersTimer; |
547 | |
548 | ChromeClient::CompositingTriggerFlags m_compositingTriggers { static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers) }; |
549 | bool m_hasAcceleratedCompositing { true }; |
550 | |
551 | CompositingPolicy m_compositingPolicy { CompositingPolicy::Normal }; |
552 | |
553 | bool m_showDebugBorders { false }; |
554 | bool m_showRepaintCounter { false }; |
555 | bool m_acceleratedDrawingEnabled { false }; |
556 | bool m_displayListDrawingEnabled { false }; |
557 | |
558 | bool m_compositing { false }; |
559 | bool m_flushingLayers { false }; |
560 | bool m_shouldFlushOnReattach { false }; |
561 | bool m_forceCompositingMode { false }; |
562 | bool m_inPostLayoutUpdate { false }; // true when it's OK to trust layout information (e.g. layer sizes and positions) |
563 | |
564 | bool m_isTrackingRepaints { false }; // Used for testing. |
565 | |
566 | unsigned m_contentLayersCount { 0 }; |
567 | unsigned m_layersWithTiledBackingCount { 0 }; |
568 | unsigned m_layerFlushCount { 0 }; |
569 | unsigned m_compositingUpdateCount { 0 }; |
570 | |
571 | RootLayerAttachment m_rootLayerAttachment { RootLayerUnattached }; |
572 | |
573 | RefPtr<GraphicsLayer> m_rootContentsLayer; |
574 | |
575 | // Enclosing clipping layer for iframe content |
576 | RefPtr<GraphicsLayer> m_clipLayer; |
577 | RefPtr<GraphicsLayer> m_scrollContainerLayer; |
578 | RefPtr<GraphicsLayer> m_scrolledContentsLayer; |
579 | |
580 | // Enclosing layer for overflow controls and the clipping layer |
581 | RefPtr<GraphicsLayer> m_overflowControlsHostLayer; |
582 | |
583 | // Layers for overflow controls |
584 | RefPtr<GraphicsLayer> m_layerForHorizontalScrollbar; |
585 | RefPtr<GraphicsLayer> m_layerForVerticalScrollbar; |
586 | RefPtr<GraphicsLayer> m_layerForScrollCorner; |
587 | #if ENABLE(RUBBER_BANDING) |
588 | RefPtr<GraphicsLayer> m_layerForOverhangAreas; |
589 | RefPtr<GraphicsLayer> m_contentShadowLayer; |
590 | RefPtr<GraphicsLayer> m_layerForTopOverhangArea; |
591 | RefPtr<GraphicsLayer> m_layerForBottomOverhangArea; |
592 | RefPtr<GraphicsLayer> m_layerForHeader; |
593 | RefPtr<GraphicsLayer> m_layerForFooter; |
594 | #endif |
595 | |
596 | std::unique_ptr<GraphicsLayerUpdater> m_layerUpdater; // Updates tiled layer visible area periodically while animations are running. |
597 | |
598 | Timer m_layerFlushTimer; |
599 | |
600 | bool m_layerFlushThrottlingEnabled { false }; |
601 | bool m_layerFlushThrottlingTemporarilyDisabledForInteraction { false }; |
602 | bool m_hasPendingLayerFlush { false }; |
603 | bool m_viewBackgroundIsTransparent { false }; |
604 | |
605 | #if !LOG_DISABLED |
606 | int m_rootLayerUpdateCount { 0 }; |
607 | int m_obligateCompositedLayerCount { 0 }; // count of layer that have to be composited. |
608 | int m_secondaryCompositedLayerCount { 0 }; // count of layers that have to be composited because of stacking or overlap. |
609 | double m_obligatoryBackingStoreBytes { 0 }; |
610 | double m_secondaryBackingStoreBytes { 0 }; |
611 | #endif |
612 | |
613 | Color m_viewBackgroundColor; |
614 | Color m_rootExtendedBackgroundColor; |
615 | |
616 | HashMap<ScrollingNodeID, RenderLayer*> m_scrollingNodeToLayerMap; |
617 | #if PLATFORM(IOS_FAMILY) |
618 | std::unique_ptr<LegacyWebKitScrollingLayerCoordinator> m_legacyScrollingLayerCoordinator; |
619 | #endif |
620 | }; |
621 | |
622 | void paintScrollbar(Scrollbar*, GraphicsContext&, const IntRect& clip); |
623 | |
624 | WTF::TextStream& operator<<(WTF::TextStream&, CompositingUpdateType); |
625 | WTF::TextStream& operator<<(WTF::TextStream&, CompositingPolicy); |
626 | |
627 | } // namespace WebCore |
628 | |
629 | #if ENABLE(TREE_DEBUGGING) |
630 | // Outside the WebCore namespace for ease of invocation from the debugger. |
631 | void showGraphicsLayerTreeForCompositor(WebCore::RenderLayerCompositor&); |
632 | #endif |
633 | |