[Threaded Compositor] Content and viewport sizes are mixed
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / CoordinatedGraphics / ThreadedCoordinatedLayerTreeHost.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4  * Copyright (C) 2012 Company 100, Inc.
5  * Copyright (C) 2014 Igalia S.L.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "ThreadedCoordinatedLayerTreeHost.h"
31
32 #if USE(COORDINATED_GRAPHICS_THREADED)
33
34 #include "DrawingAreaImpl.h"
35 #include "NotImplemented.h"
36 #include "ThreadSafeCoordinatedSurface.h"
37 #include "WebPage.h"
38 #include <WebCore/CoordinatedGraphicsLayer.h>
39 #include <WebCore/CoordinatedGraphicsState.h>
40 #include <WebCore/Frame.h>
41 #include <WebCore/FrameView.h>
42 #include <WebCore/GraphicsContext.h>
43 #include <WebCore/MainFrame.h>
44 #include <WebCore/Page.h>
45 #include <wtf/CurrentTime.h>
46
47 using namespace WebCore;
48
49 namespace WebKit {
50
51 Ref<ThreadedCoordinatedLayerTreeHost> ThreadedCoordinatedLayerTreeHost::create(WebPage& webPage)
52 {
53     return adoptRef(*new ThreadedCoordinatedLayerTreeHost(webPage));
54 }
55
56 ThreadedCoordinatedLayerTreeHost::~ThreadedCoordinatedLayerTreeHost()
57 {
58 }
59
60 ThreadedCoordinatedLayerTreeHost::ThreadedCoordinatedLayerTreeHost(WebPage& webPage)
61     : LayerTreeHost(webPage)
62     , m_forceRepaintAsyncCallbackID(0)
63     , m_notifyAfterScheduledLayerFlush(false)
64     , m_isSuspended(false)
65     , m_isWaitingForRenderer(false)
66     , m_layerFlushTimer(RunLoop::main(), this, &ThreadedCoordinatedLayerTreeHost::performScheduledLayerFlush)
67     , m_layerFlushSchedulingEnabled(true)
68 {
69     m_coordinator = std::make_unique<CompositingCoordinator>(m_webPage.corePage(), this);
70
71     m_coordinator->createRootLayer(m_webPage.size());
72
73     CoordinatedSurface::setFactory(createCoordinatedSurface);
74
75     m_compositor = ThreadedCompositor::create(this);
76     scheduleLayerFlush();
77 }
78
79 RefPtr<CoordinatedSurface> ThreadedCoordinatedLayerTreeHost::createCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags)
80 {
81     return ThreadSafeCoordinatedSurface::create(size, flags);
82 }
83
84 void ThreadedCoordinatedLayerTreeHost::scheduleLayerFlush()
85 {
86     if (!m_layerFlushSchedulingEnabled)
87         return;
88
89     if (!m_layerFlushTimer.isActive())
90         m_layerFlushTimer.startOneShot(0);
91 }
92
93 void ThreadedCoordinatedLayerTreeHost::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
94 {
95     if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
96         return;
97
98     m_layerFlushSchedulingEnabled = layerFlushingEnabled;
99
100     if (m_layerFlushSchedulingEnabled) {
101         scheduleLayerFlush();
102         return;
103     }
104
105     cancelPendingLayerFlush();
106 }
107
108 void ThreadedCoordinatedLayerTreeHost::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
109 {
110     m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
111 }
112
113 void ThreadedCoordinatedLayerTreeHost::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
114 {
115     m_coordinator->setRootCompositingLayer(graphicsLayer);
116 }
117
118 void ThreadedCoordinatedLayerTreeHost::invalidate()
119 {
120     notImplemented();
121 }
122
123 void ThreadedCoordinatedLayerTreeHost::scrollNonCompositedContents(const WebCore::IntRect& rect)
124 {
125     m_compositor->scrollTo(rect.location());
126     scheduleLayerFlush();
127 }
128
129 void ThreadedCoordinatedLayerTreeHost::forceRepaint()
130 {
131     notImplemented();
132 }
133
134 bool ThreadedCoordinatedLayerTreeHost::forceRepaintAsync(uint64_t callbackID)
135 {
136     // We expect the UI process to not require a new repaint until the previous one has finished.
137     ASSERT(!m_forceRepaintAsyncCallbackID);
138     m_forceRepaintAsyncCallbackID = callbackID;
139     scheduleLayerFlush();
140     return true;
141 }
142
143 void ThreadedCoordinatedLayerTreeHost::contentsSizeChanged(const WebCore::IntSize& newSize)
144 {
145     m_compositor->didChangeContentsSize(newSize);
146 }
147
148 void ThreadedCoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
149 {
150     m_coordinator->deviceOrPageScaleFactorChanged();
151     m_compositor->setDeviceScaleFactor(m_webPage.deviceScaleFactor());
152 }
153
154 void ThreadedCoordinatedLayerTreeHost::pauseRendering()
155 {
156     m_isSuspended = true;
157 }
158
159 void ThreadedCoordinatedLayerTreeHost::resumeRendering()
160 {
161     m_isSuspended = false;
162     scheduleLayerFlush();
163 }
164
165 GraphicsLayerFactory* ThreadedCoordinatedLayerTreeHost::graphicsLayerFactory()
166 {
167     return m_coordinator.get();
168 }
169
170 void ThreadedCoordinatedLayerTreeHost::sizeDidChange(const WebCore::IntSize& size)
171 {
172     m_coordinator->sizeDidChange(size);
173     m_compositor->didChangeViewportSize(size);
174 }
175
176 void ThreadedCoordinatedLayerTreeHost::didChangeViewportProperties(const WebCore::ViewportAttributes& attr)
177 {
178     m_compositor->didChangeViewportAttribute(attr);
179 }
180
181 void ThreadedCoordinatedLayerTreeHost::compositorDidFlushLayers()
182 {
183     static_cast<DrawingAreaImpl*>(m_webPage.drawingArea())->layerHostDidFlushLayers();
184 }
185
186 void ThreadedCoordinatedLayerTreeHost::didScaleFactorChanged(float scale, const IntPoint& origin)
187 {
188     m_webPage.scalePage(scale, origin);
189 }
190
191 void ThreadedCoordinatedLayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* graphicsLayer)
192 {
193     m_coordinator->setViewOverlayRootLayer(graphicsLayer);
194 }
195
196 #if PLATFORM(GTK)
197 void ThreadedCoordinatedLayerTreeHost::setNativeSurfaceHandleForCompositing(uint64_t handle)
198 {
199     m_layerTreeContext.contextID = handle;
200     m_compositor->setNativeSurfaceHandleForCompositing(handle);
201 }
202 #endif
203
204 #if ENABLE(REQUEST_ANIMATION_FRAME)
205 void ThreadedCoordinatedLayerTreeHost::scheduleAnimation()
206 {
207     if (m_isWaitingForRenderer)
208         return;
209
210     if (m_layerFlushTimer.isActive())
211         return;
212
213     m_layerFlushTimer.startOneShot(m_coordinator->nextAnimationServiceTime());
214     scheduleLayerFlush();
215 }
216 #endif
217
218 void ThreadedCoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector, float scale)
219 {
220     m_coordinator->setVisibleContentsRect(rect, trajectoryVector);
221     if (m_lastScrollPosition != roundedIntPoint(rect.location())) {
222         m_lastScrollPosition = roundedIntPoint(rect.location());
223
224         if (!m_webPage.corePage()->mainFrame().view()->useFixedLayout())
225             m_webPage.corePage()->mainFrame().view()->notifyScrollPositionChanged(m_lastScrollPosition);
226     }
227
228     if (m_lastScaleFactor != scale) {
229         m_lastScaleFactor = scale;
230         didScaleFactorChanged(m_lastScaleFactor, m_lastScrollPosition);
231     }
232
233     scheduleLayerFlush();
234 }
235
236 void ThreadedCoordinatedLayerTreeHost::cancelPendingLayerFlush()
237 {
238     m_layerFlushTimer.stop();
239 }
240
241 void ThreadedCoordinatedLayerTreeHost::performScheduledLayerFlush()
242 {
243     if (m_isSuspended || m_isWaitingForRenderer)
244         return;
245
246     m_coordinator->syncDisplayState();
247     bool didSync = m_coordinator->flushPendingLayerChanges();
248
249     if (m_notifyAfterScheduledLayerFlush && didSync) {
250         compositorDidFlushLayers();
251         m_notifyAfterScheduledLayerFlush = false;
252     }
253 }
254
255 void ThreadedCoordinatedLayerTreeHost::purgeBackingStores()
256 {
257     m_coordinator->purgeBackingStores();
258 }
259
260 void ThreadedCoordinatedLayerTreeHost::renderNextFrame()
261 {
262     m_isWaitingForRenderer = false;
263     m_coordinator->renderNextFrame();
264     scheduleLayerFlush();
265 }
266
267 void ThreadedCoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const IntSize& offset)
268 {
269     m_coordinator->commitScrollOffset(layerID, offset);
270 }
271
272 void ThreadedCoordinatedLayerTreeHost::notifyFlushRequired()
273 {
274     scheduleLayerFlush();
275 }
276
277 void ThreadedCoordinatedLayerTreeHost::commitSceneState(const CoordinatedGraphicsState& state)
278 {
279     m_isWaitingForRenderer = true;
280     m_compositor->updateSceneState(state);
281 }
282
283 void ThreadedCoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer*, GraphicsContext&, const IntRect&)
284 {
285 }
286
287 } // namespace WebKit
288
289 #endif // USE(COORDINATED_GRAPHICS)