c3147ae60f07534183352f20930d2a0f90ae522e
[framework/web/webkit-efl.git] / Source / WebKit2 / UIProcess / LayerTreeCoordinatorProxy.cpp
1 /*
2     Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Library General Public
6     License as published by the Free Software Foundation; either
7     version 2 of the License, or (at your option) any later version.
8
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     Library General Public License for more details.
13
14     You should have received a copy of the GNU Library General Public License
15     along with this library; see the file COPYING.LIB.  If not, write to
16     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #if USE(UI_SIDE_COMPOSITING)
23 #include "LayerTreeCoordinatorProxy.h"
24
25 #include "LayerTreeCoordinatorMessages.h"
26 #include "UpdateInfo.h"
27 #include "WebCoreArgumentCoders.h"
28 #include "WebLayerTreeInfo.h"
29 #include "WebLayerTreeRenderer.h"
30 #include "WebPageProxy.h"
31 #include "WebProcessProxy.h"
32 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
33 #include "WebLayerTreeRendererTizen.h"
34 #endif
35
36 #include <EGL/egl.h>
37 #include <X11/Xlib.h>
38
39 namespace WebKit {
40
41 using namespace WebCore;
42
43 // FIXME: This function needs a better place
44 static bool supportsLockSurfaceExtension()
45 {
46     static bool extSupportQueried = false;
47     static bool supportLockSurfaceExt = false;
48
49     if (extSupportQueried)
50         return supportLockSurfaceExt;
51
52     extSupportQueried = true;
53     Display* nativeDisplay = 0;
54     EGLDisplay display = eglGetCurrentDisplay();
55
56     if (display == EGL_NO_DISPLAY) {
57         nativeDisplay = XOpenDisplay(0);
58         display = eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(nativeDisplay));
59         eglInitialize(display, 0, 0);
60     }
61
62     if (display != EGL_NO_DISPLAY) {
63         String rawExtensions = reinterpret_cast<const char*>(eglQueryString(display, EGL_EXTENSIONS));
64         Vector<String> extNames;
65         rawExtensions.lower().split(" ", extNames);
66
67         if (extNames.contains("egl_khr_lock_surface"))
68             supportLockSurfaceExt = true;
69
70         extNames.clear();
71     }
72
73     return supportLockSurfaceExt;
74 }
75
76 LayerTreeCoordinatorProxy::LayerTreeCoordinatorProxy(DrawingAreaProxy* drawingAreaProxy)
77     : m_drawingAreaProxy(drawingAreaProxy)
78 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC)
79     , m_renderer(adoptRef(new WebLayerTreeRenderer(this)))
80 #else
81     , m_renderer(adoptRef(new WebLayerTreeRenderer(this, drawingAreaProxy)))
82 #endif
83 {
84 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
85     m_renderer->setActive(true);
86 #endif
87 }
88
89 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
90 LayerTreeCoordinatorProxy::LayerTreeCoordinatorProxy(DrawingAreaProxy* drawingAreaProxy, bool isGLMode)
91     : m_drawingAreaProxy(drawingAreaProxy)
92 {
93 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
94     WebLayerTreeRenderer* renderer = (isGLMode && supportsLockSurfaceExtension()) ? new WebLayerTreeRendererTizen(this, drawingAreaProxy) : new WebLayerTreeRenderer(this, drawingAreaProxy, isGLMode);
95     m_renderer = adoptRef(renderer);
96 #else
97     m_renderer = adoptRef(new WebLayerTreeRenderer(this, drawingAreaProxy, isGLMode));
98 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
99     m_renderer->setActive(true);
100 }
101 #endif // ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
102
103 LayerTreeCoordinatorProxy::~LayerTreeCoordinatorProxy()
104 {
105     m_renderer->detach();
106 }
107
108 void LayerTreeCoordinatorProxy::updateViewport()
109 {
110     m_drawingAreaProxy->updateViewport();
111 }
112
113 void LayerTreeCoordinatorProxy::dispatchUpdate(const Function<void()>& function)
114 {
115     m_renderer->appendUpdate(function);
116 }
117
118 void LayerTreeCoordinatorProxy::createTileForLayer(int layerID, int tileID, const IntRect& targetRect, const WebKit::SurfaceUpdateInfo& updateInfo)
119 {
120     dispatchUpdate(bind(&WebLayerTreeRenderer::createTile, m_renderer.get(), layerID, tileID, updateInfo.scaleFactor));
121     updateTileForLayer(layerID, tileID, targetRect, updateInfo);
122 }
123
124 void LayerTreeCoordinatorProxy::updateTileForLayer(int layerID, int tileID, const IntRect& targetRect, const WebKit::SurfaceUpdateInfo& updateInfo)
125 {
126     RefPtr<ShareableSurface> surface;
127 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
128     if (!m_renderer->isUsingPlatformSurface()) {
129 #endif
130 #if USE(GRAPHICS_SURFACE)
131     int token = updateInfo.surfaceHandle.graphicsSurfaceToken();
132     if (token) {
133         HashMap<uint32_t, RefPtr<ShareableSurface> >::iterator it = m_surfaces.find(token);
134         if (it == m_surfaces.end()) {
135             surface = ShareableSurface::create(updateInfo.surfaceHandle);
136             m_surfaces.add(token, surface);
137         } else
138             surface = it->second;
139     } else
140         surface = ShareableSurface::create(updateInfo.surfaceHandle);
141 #else
142     surface = ShareableSurface::create(updateInfo.surfaceHandle);
143 #endif
144 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
145     }
146 #endif
147
148 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
149 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
150     if (m_renderer->isUsingPlatformSurface())
151         dispatchUpdate(bind(&WebLayerTreeRenderer::updateTileWithUpdateInfo, m_renderer.get(), layerID, tileID, WebLayerTreeRenderer::TileUpdate(updateInfo.updateRect, targetRect, surface, updateInfo.surfaceOffset, updateInfo.platformSurfaceID, updateInfo.platformSurfaceSize)));
152     else
153 #endif
154         dispatchUpdate(bind(&WebLayerTreeRenderer::updateTileWithUpdateInfo, m_renderer.get(), layerID, tileID, WebLayerTreeRenderer::TileUpdate(updateInfo.updateRect, targetRect, surface, updateInfo.surfaceOffset)));
155 #else
156 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
157         dispatchUpdate(bind(&WebLayerTreeRenderer::updatePlatformSurfaceTile, m_renderer.get(), layerID, tileID, updateInfo.updateRect, updateInfo.platformSurfaceID, updateInfo.platformSurfaceSize));
158 #else
159         dispatchUpdate(bind(&WebLayerTreeRenderer::updateTile, m_renderer.get(), layerID, tileID, WebLayerTreeRenderer::TileUpdate(updateInfo.updateRect, targetRect, surface, updateInfo.surfaceOffset)));
160 #endif
161 #endif
162 }
163
164 void LayerTreeCoordinatorProxy::removeTileForLayer(int layerID, int tileID)
165 {
166     dispatchUpdate(bind(&WebLayerTreeRenderer::removeTile, m_renderer.get(), layerID, tileID));
167 }
168
169 void LayerTreeCoordinatorProxy::deleteCompositingLayer(WebLayerID id)
170 {
171     dispatchUpdate(bind(&WebLayerTreeRenderer::deleteLayer, m_renderer.get(), id));
172 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC)
173     // For efl port, we should not call updateViewport here immediately.
174     // This may trigger rendering with broken LayerTreeHost.
175     // And actually, we don't need to call this here, because it will be called by didRenderFrame for each update of LayerTreeHost.
176     updateViewport();
177 #endif
178 }
179
180 void LayerTreeCoordinatorProxy::setRootCompositingLayer(WebLayerID id)
181 {
182     dispatchUpdate(bind(&WebLayerTreeRenderer::setRootLayerID, m_renderer.get(), id));
183     updateViewport();
184 }
185
186 void LayerTreeCoordinatorProxy::setCompositingLayerState(WebLayerID id, const WebLayerInfo& info)
187 {
188     dispatchUpdate(bind(&WebLayerTreeRenderer::setLayerState, m_renderer.get(), id, info));
189 }
190
191 void LayerTreeCoordinatorProxy::setCompositingLayerChildren(WebLayerID id, const Vector<WebLayerID>& children)
192 {
193     dispatchUpdate(bind(&WebLayerTreeRenderer::setLayerChildren, m_renderer.get(), id, children));
194 }
195
196 #if ENABLE(CSS_FILTERS)
197 void LayerTreeCoordinatorProxy::setCompositingLayerFilters(WebLayerID id, const FilterOperations& filters)
198 {
199     dispatchUpdate(bind(&WebLayerTreeRenderer::setLayerFilters, m_renderer.get(), id, filters));
200 }
201 #endif
202
203 void LayerTreeCoordinatorProxy::didRenderFrame()
204 {
205 #if OS(TIZEN)
206     m_drawingAreaProxy->page()->didRenderFrame();
207 #endif
208     dispatchUpdate(bind(&WebLayerTreeRenderer::flushLayerChanges, m_renderer.get()));
209 #if OS(TIZEN)
210     m_renderer->syncRemoteContent();
211 #endif
212     updateViewport();
213 }
214
215 void LayerTreeCoordinatorProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle)
216 {
217     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
218     dispatchUpdate(bind(&WebLayerTreeRenderer::createImage, m_renderer.get(), key, bitmap));
219 }
220
221 void LayerTreeCoordinatorProxy::destroyDirectlyCompositedImage(int64_t key)
222 {
223     dispatchUpdate(bind(&WebLayerTreeRenderer::destroyImage, m_renderer.get(), key));
224 }
225
226 void LayerTreeCoordinatorProxy::setContentsSize(const FloatSize& contentsSize)
227 {
228     dispatchUpdate(bind(&WebLayerTreeRenderer::setContentsSize, m_renderer.get(), contentsSize));
229 }
230
231 void LayerTreeCoordinatorProxy::setLayerAnimations(WebLayerID id, const GraphicsLayerAnimations& animations)
232 {
233     dispatchUpdate(bind(&WebLayerTreeRenderer::setLayerAnimations, m_renderer.get(), id, animations));
234 }
235
236 void LayerTreeCoordinatorProxy::setAnimationsLocked(bool locked)
237 {
238     dispatchUpdate(bind(&WebLayerTreeRenderer::setAnimationsLocked, m_renderer.get(), locked));
239 }
240
241 void LayerTreeCoordinatorProxy::setVisibleContentsRect(const IntRect& rect, float scale, const FloatPoint& trajectoryVector, const WebCore::FloatPoint& accurateVisibleContentsPosition)
242 {
243 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
244     m_renderer->setVisibleContentsRect(rect, scale, accurateVisibleContentsPosition);
245 #else
246     dispatchUpdate(bind(&WebLayerTreeRenderer::setVisibleContentsRect, m_renderer.get(), rect, scale, accurateVisibleContentsPosition));
247 #endif
248     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRect(rect, scale, trajectoryVector), m_drawingAreaProxy->page()->pageID());
249 }
250
251 void LayerTreeCoordinatorProxy::renderNextFrame()
252 {
253     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::RenderNextFrame(), m_drawingAreaProxy->page()->pageID());
254 }
255
256 void LayerTreeCoordinatorProxy::didChangeScrollPosition(const IntPoint& position)
257 {
258     dispatchUpdate(bind(&WebLayerTreeRenderer::didChangeScrollPosition, m_renderer.get(), position));
259 }
260
261 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
262 void LayerTreeCoordinatorProxy::syncCanvas(uint32_t id, const IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer, int flags)
263 {
264     dispatchUpdate(bind(&WebLayerTreeRenderer::syncCanvas, m_renderer.get(), id, canvasSize, graphicsSurfaceToken, frontBuffer, flags));
265 }
266 #else
267 void LayerTreeCoordinatorProxy::syncCanvas(uint32_t id, const IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer)
268 {
269     dispatchUpdate(bind(&WebLayerTreeRenderer::syncCanvas, m_renderer.get(), id, canvasSize, graphicsSurfaceToken, frontBuffer));
270 }
271 #endif
272
273 void LayerTreeCoordinatorProxy::purgeBackingStores()
274 {
275     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID());
276 }
277
278 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
279 void LayerTreeCoordinatorProxy::clearBackingStores()
280 {
281     m_renderer->syncRemoteContent();
282     m_renderer->clearBackingStores();
283     purgeBackingStores();
284 }
285 #endif
286
287 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
288 bool LayerTreeCoordinatorProxy::hasOverflowLayer() const
289 {
290     return m_renderer->scrollingContentsLayerCounts() ? true : false;
291 }
292 #endif
293
294 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
295 bool LayerTreeCoordinatorProxy::setOffsetForFocusedScrollingContentsLayer(const WebCore::FloatPoint& offset)
296 {
297     return m_renderer && m_renderer->setOffset(m_renderer->focusedLayerID(), offset);
298 }
299
300 void LayerTreeCoordinatorProxy::setVisibleContentsRectForScrollingContentsLayers(const WebCore::IntRect& visibleRect)
301 {
302     if (m_renderer)
303         m_renderer->setVisibleContentsRectForScrollingContentsLayers(visibleRect);
304 }
305 #endif
306
307 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
308 void LayerTreeCoordinatorProxy::initializeAcceleratedCompositingMode(bool isGLMode)
309 {
310     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetAccelerationMode(isGLMode), m_drawingAreaProxy->page()->pageID());
311 }
312 #endif
313
314 }
315 #endif // USE(UI_SIDE_COMPOSITING)