1/*
2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2019 Igalia S.L.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include "AcceleratedSurface.h"
30#include "CallbackID.h"
31#include "CompositingCoordinator.h"
32#include "LayerTreeContext.h"
33#include "OptionalCallbackID.h"
34#include "SimpleViewportController.h"
35#include "ThreadedCompositor.h"
36#include "ThreadedDisplayRefreshMonitor.h"
37#include <WebCore/PlatformScreen.h>
38#include <wtf/Forward.h>
39#include <wtf/OptionSet.h>
40#include <wtf/RunLoop.h>
41
42namespace WebCore {
43class IntRect;
44class IntSize;
45class GraphicsLayer;
46class GraphicsLayerFactory;
47struct CoordinatedGraphicsState;
48struct ViewportAttributes;
49}
50
51namespace WebKit {
52
53class WebPage;
54
55class LayerTreeHost
56#if USE(COORDINATED_GRAPHICS)
57 final : public CompositingCoordinator::Client, public AcceleratedSurface::Client
58#endif
59{
60 WTF_MAKE_FAST_ALLOCATED;
61public:
62 explicit LayerTreeHost(WebPage&);
63 ~LayerTreeHost();
64
65 const LayerTreeContext& layerTreeContext() const { return m_layerTreeContext; }
66 void setLayerFlushSchedulingEnabled(bool);
67 void setShouldNotifyAfterNextScheduledLayerFlush(bool);
68
69 void scheduleLayerFlush();
70 void cancelPendingLayerFlush();
71 void setRootCompositingLayer(WebCore::GraphicsLayer*);
72 void setViewOverlayRootLayer(WebCore::GraphicsLayer*);
73 void invalidate();
74
75 void scrollNonCompositedContents(const WebCore::IntRect&);
76 void forceRepaint();
77 bool forceRepaintAsync(CallbackID);
78 void sizeDidChange(const WebCore::IntSize& newSize);
79
80 void pauseRendering();
81 void resumeRendering();
82
83 WebCore::GraphicsLayerFactory* graphicsLayerFactory();
84
85 void contentsSizeChanged(const WebCore::IntSize&);
86 void didChangeViewportAttributes(WebCore::ViewportAttributes&&);
87
88 void setIsDiscardable(bool);
89
90#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK)
91 void setNativeSurfaceHandleForCompositing(uint64_t);
92#endif
93
94 void deviceOrPageScaleFactorChanged();
95
96#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
97 RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID);
98#endif
99
100private:
101#if USE(COORDINATED_GRAPHICS)
102 void layerFlushTimerFired();
103 void didChangeViewport();
104 void renderNextFrame(bool);
105
106 // CompositingCoordinator::Client
107 void didFlushRootLayer(const WebCore::FloatRect& visibleContentRect) override;
108 void notifyFlushRequired() override { scheduleLayerFlush(); };
109 void commitSceneState(const WebCore::CoordinatedGraphicsState&) override;
110
111 // AcceleratedSurface::Client
112 void frameComplete() override;
113
114 uint64_t nativeSurfaceHandleForCompositing();
115 void didDestroyGLContext();
116 void willRenderFrame();
117 void didRenderFrame();
118 void requestDisplayRefreshMonitorUpdate();
119 void handleDisplayRefreshMonitorUpdate(bool);
120
121 class CompositorClient final : public ThreadedCompositor::Client, public ThreadedDisplayRefreshMonitor::Client {
122 WTF_MAKE_NONCOPYABLE(CompositorClient);
123 public:
124 CompositorClient(LayerTreeHost& layerTreeHost)
125 : m_layerTreeHost(layerTreeHost)
126 {
127 }
128
129 private:
130 uint64_t nativeSurfaceHandleForCompositing() override
131 {
132 return m_layerTreeHost.nativeSurfaceHandleForCompositing();
133 }
134
135 void didDestroyGLContext() override
136 {
137 m_layerTreeHost.didDestroyGLContext();
138 }
139
140 void resize(const WebCore::IntSize& size) override
141 {
142 if (m_layerTreeHost.m_surface)
143 m_layerTreeHost.m_surface->clientResize(size);
144 }
145
146 void willRenderFrame() override
147 {
148 m_layerTreeHost.willRenderFrame();
149 }
150
151 void didRenderFrame() override
152 {
153 m_layerTreeHost.didRenderFrame();
154 }
155
156 void requestDisplayRefreshMonitorUpdate() override
157 {
158 m_layerTreeHost.requestDisplayRefreshMonitorUpdate();
159 }
160
161 void handleDisplayRefreshMonitorUpdate(bool hasBeenRescheduled) override
162 {
163 m_layerTreeHost.handleDisplayRefreshMonitorUpdate(hasBeenRescheduled);
164 }
165
166 LayerTreeHost& m_layerTreeHost;
167 };
168
169 enum class DiscardableSyncActions {
170 UpdateSize = 1 << 1,
171 UpdateViewport = 1 << 2,
172 UpdateScale = 1 << 3
173 };
174#endif // USE(COORDINATED_GRAPHICS)
175
176 WebPage& m_webPage;
177 LayerTreeContext m_layerTreeContext;
178#if USE(COORDINATED_GRAPHICS)
179 bool m_layerFlushSchedulingEnabled { true };
180 bool m_notifyAfterScheduledLayerFlush { false };
181 bool m_isSuspended { false };
182 bool m_isValid { true };
183 bool m_isWaitingForRenderer { false };
184 bool m_scheduledWhileWaitingForRenderer { false };
185 float m_lastPageScaleFactor { 1 };
186 WebCore::IntPoint m_lastScrollPosition;
187 bool m_isDiscardable { false };
188 OptionSet<DiscardableSyncActions> m_discardableSyncActions;
189 WebCore::GraphicsLayer* m_viewOverlayRootLayer { nullptr };
190 CompositingCoordinator m_coordinator;
191 CompositorClient m_compositorClient;
192 std::unique_ptr<AcceleratedSurface> m_surface;
193 RefPtr<ThreadedCompositor> m_compositor;
194 SimpleViewportController m_viewportController;
195 struct {
196 OptionalCallbackID callbackID;
197 bool needsFreshFlush { false };
198 } m_forceRepaintAsync;
199 RunLoop::Timer<LayerTreeHost> m_layerFlushTimer;
200#endif // USE(COORDINATED_GRAPHICS)
201};
202
203#if !USE(COORDINATED_GRAPHICS)
204inline LayerTreeHost::LayerTreeHost(WebPage& webPage) : m_webPage(webPage) { }
205inline LayerTreeHost::~LayerTreeHost() { }
206inline void LayerTreeHost::setLayerFlushSchedulingEnabled(bool) { }
207inline void LayerTreeHost::setShouldNotifyAfterNextScheduledLayerFlush(bool) { }
208inline void LayerTreeHost::scheduleLayerFlush() { }
209inline void LayerTreeHost::cancelPendingLayerFlush() { }
210inline void LayerTreeHost::setRootCompositingLayer(WebCore::GraphicsLayer*) { }
211inline void LayerTreeHost::setViewOverlayRootLayer(WebCore::GraphicsLayer*) { }
212inline void LayerTreeHost::invalidate() { }
213inline void LayerTreeHost::scrollNonCompositedContents(const WebCore::IntRect&) { }
214inline void LayerTreeHost::forceRepaint() { }
215inline bool LayerTreeHost::forceRepaintAsync(CallbackID) { return false; }
216inline void LayerTreeHost::sizeDidChange(const WebCore::IntSize&) { }
217inline void LayerTreeHost::pauseRendering() { }
218inline void LayerTreeHost::resumeRendering() { }
219inline WebCore::GraphicsLayerFactory* LayerTreeHost::graphicsLayerFactory() { return nullptr; }
220inline void LayerTreeHost::contentsSizeChanged(const WebCore::IntSize&) { }
221inline void LayerTreeHost::didChangeViewportAttributes(WebCore::ViewportAttributes&&) { }
222inline void LayerTreeHost::setIsDiscardable(bool) { }
223inline void LayerTreeHost::deviceOrPageScaleFactorChanged() { }
224#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
225inline RefPtr<WebCore::DisplayRefreshMonitor> LayerTreeHost::createDisplayRefreshMonitor(WebCore::PlatformDisplayID) { return nullptr; }
226#endif
227#endif
228
229} // namespace WebKit
230