1 | /* |
2 | * Copyright (C) 2011 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). |
4 | * Copyright (C) 2019 Igalia S.L. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
17 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | * THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #pragma once |
29 | |
30 | #include "DrawingArea.h" |
31 | #include <WebCore/Region.h> |
32 | #include <wtf/RunLoop.h> |
33 | |
34 | namespace WebCore { |
35 | class GraphicsContext; |
36 | } |
37 | |
38 | namespace WebKit { |
39 | |
40 | class ShareableBitmap; |
41 | class UpdateInfo; |
42 | |
43 | class DrawingAreaCoordinatedGraphics final : public DrawingArea { |
44 | public: |
45 | DrawingAreaCoordinatedGraphics(WebPage&, const WebPageCreationParameters&); |
46 | virtual ~DrawingAreaCoordinatedGraphics(); |
47 | |
48 | private: |
49 | // DrawingArea |
50 | void setNeedsDisplay() override; |
51 | void setNeedsDisplayInRect(const WebCore::IntRect&) override; |
52 | void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta) override; |
53 | void forceRepaint() override; |
54 | bool forceRepaintAsync(CallbackID) override; |
55 | |
56 | void setLayerTreeStateIsFrozen(bool) override; |
57 | bool layerTreeStateIsFrozen() const override { return m_layerTreeStateIsFrozen; } |
58 | |
59 | void setPaintingEnabled(bool paintingEnabled) override { m_isPaintingEnabled = paintingEnabled; }; |
60 | void updatePreferences(const WebPreferencesStore&) override; |
61 | void mainFrameContentSizeChanged(const WebCore::IntSize&) override; |
62 | void deviceOrPageScaleFactorChanged() override; |
63 | void didChangeViewportAttributes(WebCore::ViewportAttributes&&) override; |
64 | |
65 | WebCore::GraphicsLayerFactory* graphicsLayerFactory() override; |
66 | void setRootCompositingLayer(WebCore::GraphicsLayer*) override; |
67 | void scheduleInitialDeferredPaint() override { }; |
68 | void scheduleCompositingLayerFlush() override; |
69 | void scheduleCompositingLayerFlushImmediately() override { scheduleCompositingLayerFlush(); }; |
70 | void layerHostDidFlushLayers() override; |
71 | |
72 | #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) |
73 | RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) override; |
74 | #endif |
75 | |
76 | void activityStateDidChange(OptionSet<WebCore::ActivityState::Flag>, ActivityStateChangeID, const Vector<CallbackID>& /* callbackIDs */) override; |
77 | void attachViewOverlayGraphicsLayer(WebCore::GraphicsLayer*) override; |
78 | |
79 | // IPC message handlers. |
80 | void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset) override; |
81 | void didUpdate() override; |
82 | |
83 | void sendDidUpdateBackingStoreState(); |
84 | |
85 | void exitAcceleratedCompositingModeSoon(); |
86 | bool exitAcceleratedCompositingModePending() const { return m_exitCompositingTimer.isActive(); } |
87 | void discardPreviousLayerTreeHost(); |
88 | |
89 | void suspendPainting(); |
90 | void resumePainting(); |
91 | |
92 | void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*); |
93 | void exitAcceleratedCompositingMode(); |
94 | |
95 | void scheduleDisplay(); |
96 | void displayTimerFired(); |
97 | void display(); |
98 | void display(UpdateInfo&); |
99 | |
100 | uint64_t m_backingStoreStateID { 0 }; |
101 | |
102 | // Whether painting is enabled. If painting is disabled, any calls to setNeedsDisplay and scroll are ignored. |
103 | bool m_isPaintingEnabled { true }; |
104 | |
105 | // Whether we're currently processing an UpdateBackingStoreState message. |
106 | bool m_inUpdateBackingStoreState { false }; |
107 | |
108 | // When true, we should send an UpdateBackingStoreState message instead of any other messages |
109 | // we normally send to the UI process. |
110 | bool m_shouldSendDidUpdateBackingStoreState { false }; |
111 | |
112 | // True between sending the 'enter compositing' messages, and the 'exit compositing' message. |
113 | bool m_compositingAccordingToProxyMessages { false }; |
114 | |
115 | // When true, we maintain the layer tree in its current state by not leaving accelerated compositing mode |
116 | // and not scheduling layer flushes. |
117 | bool m_layerTreeStateIsFrozen { false }; |
118 | |
119 | // True when we were asked to exit accelerated compositing mode but couldn't because layer tree |
120 | // state was frozen. |
121 | bool m_wantsToExitAcceleratedCompositingMode { false }; |
122 | |
123 | // Whether painting is suspended. We'll still keep track of the dirty region but we |
124 | // won't paint until painting has resumed again. |
125 | bool m_isPaintingSuspended { false }; |
126 | |
127 | RunLoop::Timer<DrawingAreaCoordinatedGraphics> m_exitCompositingTimer; |
128 | |
129 | // The layer tree host that handles accelerated compositing. |
130 | std::unique_ptr<LayerTreeHost> m_layerTreeHost; |
131 | |
132 | std::unique_ptr<LayerTreeHost> m_previousLayerTreeHost; |
133 | RunLoop::Timer<DrawingAreaCoordinatedGraphics> m_discardPreviousLayerTreeHostTimer; |
134 | |
135 | WebCore::Region m_dirtyRegion; |
136 | WebCore::IntRect m_scrollRect; |
137 | WebCore::IntSize m_scrollOffset; |
138 | |
139 | // Whether we're waiting for a DidUpdate message. Used for throttling paints so that the |
140 | // web process won't paint more frequent than the UI process can handle. |
141 | bool m_isWaitingForDidUpdate { false }; |
142 | |
143 | bool m_alwaysUseCompositing {false }; |
144 | bool m_forceRepaintAfterBackingStoreStateUpdate { false }; |
145 | |
146 | RunLoop::Timer<DrawingAreaCoordinatedGraphics> m_displayTimer; |
147 | }; |
148 | |
149 | } // namespace WebKit |
150 | |