5583da4955c026108c3eff2ab6f0c1cc97d75e3d
[framework/web/webkit-efl.git] / Source / WebKit2 / UIProcess / WebLayerTreeRenderer.cpp
1 /*
2     Copyright (C) 2012 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
24 #include "WebLayerTreeRenderer.h"
25
26 #include "GraphicsLayerTextureMapper.h"
27 #include "LayerBackingStore.h"
28 #include "LayerTreeCoordinatorProxy.h"
29 #include "MessageID.h"
30 #include "ShareableBitmap.h"
31 #include "TextureMapper.h"
32 #include "TextureMapperBackingStore.h"
33 #include "TextureMapperGL.h"
34 #include "TextureMapperLayer.h"
35 #include "UpdateInfo.h"
36 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC)
37 #include <OpenGLShims.h>
38 #endif
39 #include <WebCore/Logging.h>
40 #include <wtf/Atomics.h>
41 #include <wtf/MainThread.h>
42
43 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
44 #include "LayerTreeCoordinatorMessages.h"
45 #include "TextureMapperGL.h"
46 #endif
47
48 namespace WebKit {
49
50 using namespace WebCore;
51
52 template<class T> class MainThreadGuardedInvoker {
53 public:
54     static void call(PassRefPtr<T> objectToGuard, const Function<void()>& function)
55     {
56         MainThreadGuardedInvoker<T>* invoker = new MainThreadGuardedInvoker<T>(objectToGuard, function);
57         callOnMainThread(invoke, invoker);
58     }
59
60 private:
61     MainThreadGuardedInvoker(PassRefPtr<T> object, const Function<void()>& newFunction)
62         : objectToGuard(object)
63         , function(newFunction)
64     {
65     }
66
67     RefPtr<T> objectToGuard;
68     Function<void()> function;
69     static void invoke(void* data)
70     {
71         MainThreadGuardedInvoker<T>* invoker = static_cast<MainThreadGuardedInvoker<T>*>(data);
72         invoker->function();
73         delete invoker;
74     }
75 };
76
77 void WebLayerTreeRenderer::callOnMainThread(const Function<void()>& function)
78 {
79     if (isMainThread())
80         function();
81     else
82         MainThreadGuardedInvoker<WebLayerTreeRenderer>::call(this, function);
83 }
84
85 static FloatPoint boundedScrollPosition(const FloatPoint& scrollPosition, const FloatRect& visibleContentRect, const FloatSize& contentSize)
86 {
87 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
88     float scrollPositionX = std::max(scrollPosition.x(), 0.0f);
89     scrollPositionX = std::min(scrollPositionX, contentSize.width());
90
91     float scrollPositionY = std::max(scrollPosition.y(), 0.0f);
92     scrollPositionY = std::min(scrollPositionY, contentSize.height());
93
94     // Prevent negative scroll position.
95     scrollPositionX = std::max(scrollPositionX, 0.0f);
96     scrollPositionY = std::max(scrollPositionY, 0.0f);
97 #else
98     float scrollPositionX = std::max(scrollPosition.x(), 0.0f);
99     scrollPositionX = std::min(scrollPositionX, contentSize.width() - visibleContentRect.width());
100
101     float scrollPositionY = std::max(scrollPosition.y(), 0.0f);
102     scrollPositionY = std::min(scrollPositionY, contentSize.height() - visibleContentRect.height());
103 #endif
104
105     return FloatPoint(scrollPositionX, scrollPositionY);
106 }
107
108 WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeCoordinatorProxy* layerTreeCoordinatorProxy)
109     : m_contentsScale(1)
110     , m_layerTreeCoordinatorProxy(layerTreeCoordinatorProxy)
111     , m_rootLayerID(InvalidWebLayerID)
112     , m_isActive(false)
113     , m_animationsLocked(false)
114 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
115     , m_angle(0)
116 #endif
117 #if PLATFORM(EFL)
118     , m_updateViewportTimer(RunLoop::current(), this, &WebLayerTreeRenderer::updateViewportFired)
119 #endif
120 {
121 }
122
123 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
124 WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeCoordinatorProxy* layerTreeCoordinatorProxy, DrawingAreaProxy* drawingAreaProxy, bool isGLMode)
125     : m_contentsScale(1)
126     , m_layerTreeCoordinatorProxy(layerTreeCoordinatorProxy)
127     , m_rootLayerID(InvalidWebLayerID)
128     , m_isActive(false)
129     , m_animationsLocked(false)
130 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
131     , m_angle(0)
132 #endif
133     , m_drawingAreaProxy(drawingAreaProxy)
134     , m_isGLMode(isGLMode)
135 #if PLATFORM(EFL)
136     , m_updateViewportTimer(RunLoop::current(), this, &WebLayerTreeRenderer::updateViewportFired)
137 #endif
138 {
139 }
140 #endif
141
142 WebLayerTreeRenderer::~WebLayerTreeRenderer()
143 {
144 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
145     if (m_backupTexture && m_backupTexture->isValid()) {
146         m_backupTexture.release();
147         m_backupTexture = 0;
148     }
149 #endif
150
151 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
152     deleteAllValues(m_layers);
153 #endif
154 }
155
156 PassOwnPtr<GraphicsLayer> WebLayerTreeRenderer::createLayer(WebLayerID layerID)
157 {
158     GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this);
159     TextureMapperLayer* layer = toTextureMapperLayer(newLayer);
160     layer->setShouldUpdateBackingStoreFromLayer(false);
161
162 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
163     LOG(AcceleratedCompositing, "[UI ] create layer %u @WebLayerTreeRenderer::createLayer \n", layerID);
164 #endif
165
166     return adoptPtr(newLayer);
167 }
168
169 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
170 void WebLayerTreeRenderer::paintToBackupTexture(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const WebCore::Color& bgColor)
171 {
172     if (!m_textureMapper)
173         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
174     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
175
176     adjustPositionForFixedLayers();
177 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
178     adjustPositionForOverflowLayers();
179 #endif
180
181     GraphicsLayer* currentRootLayer = rootLayer();
182     if (!currentRootLayer)
183         return;
184
185     TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
186     if (!layer)
187         return;
188
189 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
190     static_cast<TextureMapperGL*>(m_textureMapper.get())->setAngle(m_angle);
191 #endif
192
193     if (!m_backupTexture || m_backupTexture->size() != IntSize(clipRect.width(), clipRect.height()))
194         m_backupTexture = m_textureMapper->acquireTextureFromPool(IntSize(clipRect.width(), clipRect.height()));
195
196     layer->setTextureMapper(m_textureMapper.get());
197     if (!m_animationsLocked)
198         layer->applyAnimationsRecursively();
199     m_textureMapper->bindSurface(m_backupTexture.get());
200     m_textureMapper->beginPainting(0);
201     m_textureMapper->beginClip(TransformationMatrix(), clipRect);
202
203     if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
204         currentRootLayer->setOpacity(opacity);
205         currentRootLayer->setTransform(matrix);
206         currentRootLayer->syncCompositingStateForThisLayerOnly();
207     }
208
209     glClearColor(bgColor.red(), bgColor.green(), bgColor.blue(), bgColor.alpha());
210     glClear(GL_COLOR_BUFFER_BIT);
211
212 #if ENABLE(TIZEN_TEXTURE_MAPPER_CULLER)
213     layer->paintWithCuller(clipRect);
214 #else
215     layer->paint();
216 #endif
217
218     m_textureMapper->endClip();
219     m_textureMapper->endPainting();
220     m_textureMapper->unbindSurface();
221
222     if (layer->descendantsOrSelfHaveRunningAnimations()) {
223 #if PLATFORM(EFL)
224         m_updateViewportTimer.startOneShot(0);
225 #else
226         callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this));
227 #endif
228     }
229 }
230 #endif
231
232 void WebLayerTreeRenderer::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const WebCore::Color& backgroundColor, TextureMapper::PaintFlags PaintFlags)
233 {
234     if (!m_textureMapper)
235         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
236     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
237
238     adjustPositionForFixedLayers();
239 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
240     adjustPositionForOverflowLayers();
241 #endif
242     GraphicsLayer* currentRootLayer = rootLayer();
243     if (!currentRootLayer) {
244 #if ENABLE(TIZEN_SET_INITIAL_COLOR_OF_WEBVIEW_EVAS_IMAGE)
245         glClearColor(backgroundColor.red() / 255.0f, backgroundColor.green() / 255.0f, backgroundColor.blue() / 255.0f, backgroundColor.alpha() / 255.0f);
246         glClear(GL_COLOR_BUFFER_BIT);
247 #endif
248         return;
249     }
250
251     TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
252
253     if (!layer) {
254 #if ENABLE(TIZEN_SET_INITIAL_COLOR_OF_WEBVIEW_EVAS_IMAGE)
255         glClearColor(backgroundColor.red() / 255.0f, backgroundColor.green() / 255.0f, backgroundColor.blue() / 255.0f, backgroundColor.alpha() / 255.0f);
256         glClear(GL_COLOR_BUFFER_BIT);
257 #endif
258         return;
259     }
260
261 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
262     static_cast<TextureMapperGL*>(m_textureMapper.get())->setAngle(m_angle);
263 #endif
264
265     layer->setTextureMapper(m_textureMapper.get());
266     if (!m_animationsLocked)
267         layer->applyAnimationsRecursively();
268     m_textureMapper->beginPainting(PaintFlags);
269     m_textureMapper->beginClip(TransformationMatrix(), clipRect);
270
271     m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), backgroundColor);
272
273     if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
274         currentRootLayer->setOpacity(opacity);
275         currentRootLayer->setTransform(matrix);
276         currentRootLayer->syncCompositingStateForThisLayerOnly();
277     }
278
279 #if ENABLE(TIZEN_TEXTURE_MAPPER_CULLER)
280     layer->paintWithCuller(clipRect);
281 #else
282     layer->paint();
283 #endif
284
285     m_textureMapper->endClip();
286     m_textureMapper->endPainting();
287     if (layer->descendantsOrSelfHaveRunningAnimations()) {
288 #if PLATFORM(EFL)
289         m_updateViewportTimer.startOneShot(0);
290 #else
291         callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this));
292 #endif
293     }
294 }
295
296 #if PLATFORM(QT) || PLATFORM(EFL)
297 void WebLayerTreeRenderer::paintToGraphicsContext(BackingStore::PlatformGraphicsContext painter, const WebCore::Color& backgroundColor)
298 {
299     if (!m_textureMapper)
300         m_textureMapper = TextureMapper::create();
301     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
302     syncRemoteContent();
303     TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
304
305     if (!layer)
306         return;
307
308     GraphicsContext graphicsContext(painter);
309     m_textureMapper->setGraphicsContext(&graphicsContext);
310     m_textureMapper->beginPainting();
311     m_textureMapper->drawSolidColor(graphicsContext.clipBounds(), TransformationMatrix(), backgroundColor);
312     layer->paint();
313     m_textureMapper->endPainting();
314     m_textureMapper->setGraphicsContext(0);
315 }
316 #endif
317
318 void WebLayerTreeRenderer::setContentsSize(const WebCore::FloatSize& contentsSize)
319 {
320     m_contentsSize = contentsSize;
321 }
322
323 void WebLayerTreeRenderer::setVisibleContentsRect(const IntRect& rect, float scale, const WebCore::FloatPoint& accurateVisibleContentsPosition)
324 {
325     m_visibleContentsRect = rect;
326     m_contentsScale = scale;
327     m_accurateVisibleContentsPosition = accurateVisibleContentsPosition;
328 }
329
330 #if PLATFORM(EFL)
331 void WebLayerTreeRenderer::updateViewportFired()
332 {
333     callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this));
334 }
335 #endif
336
337 void WebLayerTreeRenderer::updateViewport()
338 {
339     if (m_layerTreeCoordinatorProxy)
340         m_layerTreeCoordinatorProxy->updateViewport();
341 }
342
343 void WebLayerTreeRenderer::adjustPositionForFixedLayers()
344 {
345     if (m_fixedLayers.isEmpty())
346         return;
347
348     // Fixed layer positions are updated by the web process when we update the visible contents rect / scroll position.
349     // If we want those layers to follow accurately the viewport when we move between the web process updates, we have to offset
350     // them by the delta between the current position and the position of the viewport used for the last layout.
351     FloatPoint scrollPosition = boundedScrollPosition(FloatPoint(m_accurateVisibleContentsPosition.x() / m_contentsScale, m_accurateVisibleContentsPosition.y() / m_contentsScale), m_visibleContentsRect, m_contentsSize);
352     FloatPoint renderedScrollPosition = boundedScrollPosition(m_renderedContentsScrollPosition, m_visibleContentsRect, m_contentsSize);
353     FloatSize delta = scrollPosition - renderedScrollPosition;
354
355     LayerMap::iterator end = m_fixedLayers.end();
356     for (LayerMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
357         toTextureMapperLayer(it->second)->setScrollPositionDeltaIfNeeded(delta);
358 }
359
360 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
361 void WebLayerTreeRenderer::adjustPositionForOverflowLayers()
362 {
363     LayerMap::iterator end = m_scrollingContentsLayers.end();
364     for (LayerMap::iterator it = m_scrollingContentsLayers.begin(); it != end; ++it) {
365         GraphicsLayer* contentsLayer = it->second;
366         TextureMapperLayer* textureMapperLayer = contentsLayer ? toTextureMapperLayer(contentsLayer) : 0;
367         if (!textureMapperLayer)
368             continue;
369
370 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_SCROLLBAR)
371         const Vector<GraphicsLayer*>& childLayers = contentsLayer->children();
372         for (size_t i = 0; i < childLayers.size(); ++i)
373             if (childLayers[i]->isScrollbar())
374                 toTextureMapperLayer(childLayers[i])->setScrollPositionDeltaIfNeeded(FloatSize(contentsLayer->boundsOrigin().x(), contentsLayer->boundsOrigin().y()));
375 #endif
376         textureMapperLayer->setScrollPositionDeltaIfNeeded(FloatSize(-contentsLayer->boundsOrigin().x(), -contentsLayer->boundsOrigin().y()));
377     }
378 }
379
380 bool WebLayerTreeRenderer::setOffset(const WebLayerID id, const FloatPoint& offset)
381 {
382     LayerMap::iterator it = m_scrollingContentsLayers.find(id);
383     if (it == m_scrollingContentsLayers.end())
384         return false;
385
386     GraphicsLayer* contentsLayer = it->second;
387     GraphicsLayer* scrollingLayer = contentsLayer ? contentsLayer->parent() : 0;
388     if (!scrollingLayer)
389         return false;
390
391     const IntSize contentLayerSize(contentsLayer->size().width(), contentsLayer->size().height());
392     const IntRect boundaryRect(FloatRect(scrollingLayer->position(), scrollingLayer->size()));
393     const IntRect visibleRect(FloatRect(contentsLayer->boundsOrigin(), scrollingLayer->size()));
394
395     IntRect newVisibleRect = visibleRect;
396     newVisibleRect.moveBy(flooredIntPoint(offset));
397
398     if (newVisibleRect.x() < boundaryRect.x())
399         newVisibleRect.setX(boundaryRect.x());
400     if (contentLayerSize.width() - newVisibleRect.x() < boundaryRect.maxX())
401         newVisibleRect.setX(contentLayerSize.width() - boundaryRect.width());
402     if (newVisibleRect.y() < boundaryRect.y())
403         newVisibleRect.setY(boundaryRect.y());
404     if (contentLayerSize.height() - newVisibleRect.y() < boundaryRect.maxY())
405         newVisibleRect.setY(contentLayerSize.height() - boundaryRect.height());
406
407     if (visibleRect == newVisibleRect)
408         return false;
409
410     contentsLayer->setBoundsOrigin(newVisibleRect.location());
411
412     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(id, visibleRect, offset), m_drawingAreaProxy->page()->pageID());
413
414     return true;
415 }
416
417 void WebLayerTreeRenderer::setVisibleContentsRectForScrollingContentsLayers(const WebCore::IntRect& visibleRect)
418 {
419     LayerMap::iterator end = m_scrollingContentsLayers.end();
420     for (LayerMap::iterator it = m_scrollingContentsLayers.begin(); it != end; ++it) {
421         GraphicsLayer* contentsLayer = it->second;
422         GraphicsLayer* scrollingLayer = contentsLayer ? contentsLayer->parent() : 0;
423         if (!scrollingLayer)
424             continue;
425
426         // FIXME: We might need to check if the each content layer is in viewport.
427         // Simply, we should find out a intersected rect between visibleRect and each scrollingLayer here.
428         const IntRect newVisibleRect(FloatRect(contentsLayer->boundsOrigin(), scrollingLayer->size()));
429
430         m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(it->first, newVisibleRect, WebCore::FloatPoint()), m_drawingAreaProxy->page()->pageID());
431     }
432 }
433 #endif
434
435 void WebLayerTreeRenderer::didChangeScrollPosition(const IntPoint& position)
436 {
437     m_pendingRenderedContentsScrollPosition = position;
438 }
439
440 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
441 void WebLayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer, int flags)
442 #else
443 void WebLayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer)
444 #endif
445 {
446     if (canvasSize.isEmpty() || !m_textureMapper)
447         return;
448
449 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
450     ensureLayer(id);
451     GraphicsLayer* layer = layerByID(id);
452
453     RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore;
454     SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(id);
455     if (it == m_surfaceBackingStores.end()) {
456         canvasBackingStore = TextureMapperSurfaceBackingStore::create();
457         m_surfaceBackingStores.set(id, canvasBackingStore);
458     } else
459         canvasBackingStore = it->second;
460
461 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
462     canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize, frontBuffer, flags);
463 #else
464     canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize, frontBuffer);
465 #endif
466     layer->setContentsToMedia(canvasBackingStore.get());
467 #endif
468 }
469
470 void WebLayerTreeRenderer::setLayerChildren(WebLayerID id, const Vector<WebLayerID>& childIDs)
471 {
472     ensureLayer(id);
473     LayerMap::iterator it = m_layers.find(id);
474     GraphicsLayer* layer = it->second;
475     Vector<GraphicsLayer*> children;
476
477     for (size_t i = 0; i < childIDs.size(); ++i) {
478         WebLayerID childID = childIDs[i];
479         GraphicsLayer* child = layerByID(childID);
480         if (!child) {
481             child = createLayer(childID).leakPtr();
482             m_layers.add(childID, child);
483         }
484         children.append(child);
485     }
486     layer->setChildren(children);
487 }
488
489 #if ENABLE(CSS_FILTERS)
490 void WebLayerTreeRenderer::setLayerFilters(WebLayerID id, const FilterOperations& filters)
491 {
492     ensureLayer(id);
493     LayerMap::iterator it = m_layers.find(id);
494     ASSERT(it != m_layers.end());
495
496     GraphicsLayer* layer = it->second;
497     layer->setFilters(filters);
498 }
499 #endif
500
501 void WebLayerTreeRenderer::setLayerState(WebLayerID id, const WebLayerInfo& layerInfo)
502 {
503     ensureLayer(id);
504     LayerMap::iterator it = m_layers.find(id);
505     ASSERT(it != m_layers.end());
506
507     GraphicsLayer* layer = it->second;
508
509     layer->setReplicatedByLayer(layerByID(layerInfo.replica));
510     layer->setMaskLayer(layerByID(layerInfo.mask));
511
512     layer->setPosition(layerInfo.pos);
513     layer->setSize(layerInfo.size);
514     layer->setTransform(layerInfo.transform);
515     layer->setAnchorPoint(layerInfo.anchorPoint);
516     layer->setChildrenTransform(layerInfo.childrenTransform);
517     layer->setBackfaceVisibility(layerInfo.backfaceVisible);
518     layer->setContentsOpaque(layerInfo.contentsOpaque);
519     layer->setContentsRect(layerInfo.contentsRect);
520     layer->setContentsToBackgroundColor(layerInfo.backgroundColor);
521     layer->setDrawsContent(layerInfo.drawsContent);
522     layer->setContentsVisible(layerInfo.contentsVisible);
523     toGraphicsLayerTextureMapper(layer)->setFixedToViewport(layerInfo.fixedToViewport);
524
525     if (layerInfo.fixedToViewport)
526         m_fixedLayers.add(id, layer);
527     else
528         m_fixedLayers.remove(id);
529
530 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
531     if (layerInfo.isScrollingContentsLayer) {
532         LayerMap::iterator it = m_scrollingContentsLayers.find(id);
533         if (it == m_scrollingContentsLayers.end() || (layer->boundsOrigin() != layerInfo.boundsOrigin)) {
534             layer->setBoundsOrigin(layerInfo.boundsOrigin);
535             GraphicsLayer* scrollingLayer = layerByID(layerInfo.parent);
536             if (scrollingLayer) {
537                 const IntRect newVisibleRect(FloatRect(layer->boundsOrigin(), scrollingLayer->size()));
538                 m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(id, newVisibleRect, WebCore::FloatPoint()), m_drawingAreaProxy->page()->pageID());
539             }
540         }
541         m_scrollingContentsLayers.add(id, layer);
542     }
543     else
544         m_scrollingContentsLayers.remove(id);
545 #endif
546 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_SCROLLBAR)
547     layer->setIsScrollbar(layerInfo.isScrollbar);
548 #endif
549
550     assignImageToLayer(layer, layerInfo.imageBackingStoreID);
551
552     // Never make the root layer clip.
553     layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds);
554     layer->setOpacity(layerInfo.opacity);
555     layer->setPreserves3D(layerInfo.preserves3D);
556     if (layerInfo.isRootLayer && m_rootLayerID != id)
557         setRootLayerID(id);
558 }
559
560 void WebLayerTreeRenderer::deleteLayer(WebLayerID layerID)
561 {
562     GraphicsLayer* layer = layerByID(layerID);
563     if (!layer)
564         return;
565
566 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
567     LOG(AcceleratedCompositing, "[UI ] delete layer %u @WebLayerTreeRenderer::deleteLayer \n", layerID);
568 #endif
569
570     layer->removeFromParent();
571     m_layers.remove(layerID);
572     m_fixedLayers.remove(layerID);
573 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
574     m_scrollingContentsLayers.remove(layerID);
575 #endif
576 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
577     m_surfaceBackingStores.remove(layerID);
578 #endif
579     delete layer;
580 }
581
582
583 void WebLayerTreeRenderer::ensureLayer(WebLayerID id)
584 {
585     // We have to leak the new layer's pointer and manage it ourselves,
586     // because OwnPtr is not copyable.
587     if (m_layers.find(id) == m_layers.end())
588         m_layers.add(id, createLayer(id).leakPtr());
589 }
590
591 void WebLayerTreeRenderer::setRootLayerID(WebLayerID layerID)
592 {
593     if (layerID == m_rootLayerID)
594         return;
595
596     m_rootLayerID = layerID;
597
598     m_rootLayer->removeAllChildren();
599
600     if (!layerID)
601         return;
602
603     GraphicsLayer* layer = layerByID(layerID);
604     if (!layer)
605         return;
606
607     m_rootLayer->addChild(layer);
608 }
609
610 PassRefPtr<LayerBackingStore> WebLayerTreeRenderer::getBackingStore(WebLayerID id)
611 {
612     TextureMapperLayer* layer = toTextureMapperLayer(layerByID(id));
613     ASSERT(layer);
614     RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get());
615     if (!backingStore) {
616         backingStore = LayerBackingStore::create();
617         layer->setBackingStore(backingStore.get());
618     }
619     ASSERT(backingStore);
620     return backingStore;
621 }
622
623 void WebLayerTreeRenderer::createTile(WebLayerID layerID, int tileID, float scale)
624 {
625 #if OS(TIZEN)
626     if (!layerByID(layerID))
627         return;
628 #endif
629
630     getBackingStore(layerID)->createTile(tileID, scale);
631 }
632
633 void WebLayerTreeRenderer::removeBackingStoreIfNeeded(WebLayerID layerID)
634 {
635     TextureMapperLayer* layer = toTextureMapperLayer(layerByID(layerID));
636     ASSERT(layer);
637     RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get());
638     ASSERT(backingStore);
639     if (backingStore->isEmpty())
640         layer->setBackingStore(0);
641 }
642
643 void WebLayerTreeRenderer::removeTile(WebLayerID layerID, int tileID)
644 {
645 #if OS(TIZEN)
646     // Check whether composited graphics layer already been detached
647     GraphicsLayer* pGraphicsLayer = layerByID(layerID);
648     if (!pGraphicsLayer)
649         return;
650 #endif
651     getBackingStore(layerID)->removeTile(tileID);
652     removeBackingStoreIfNeeded(layerID);
653 }
654
655 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
656 void WebLayerTreeRenderer::updateTileWithUpdateInfo(WebLayerID layerID, int tileID, const TileUpdate& update)
657 {
658     updateTile(layerID, tileID, update);
659 }
660 #endif
661
662 void WebLayerTreeRenderer::updateTile(WebLayerID layerID, int tileID, const TileUpdate& update)
663 {
664 #if OS(TIZEN)
665     if (!layerByID(layerID))
666         return;
667 #endif
668
669     RefPtr<LayerBackingStore> backingStore = getBackingStore(layerID);
670     backingStore->updateTile(tileID, update.sourceRect, update.targetRect, update.surface, update.offset);
671     m_backingStoresWithPendingBuffers.add(backingStore);
672 }
673
674 void WebLayerTreeRenderer::createImage(int64_t imageID, PassRefPtr<ShareableBitmap> weakBitmap)
675 {
676     RefPtr<ShareableBitmap> bitmap = weakBitmap;
677     RefPtr<TextureMapperTiledBackingStore> backingStore = TextureMapperTiledBackingStore::create();
678     m_directlyCompositedImages.set(imageID, backingStore);
679     backingStore->updateContents(m_textureMapper.get(), bitmap->createImage().get());
680 }
681
682 void WebLayerTreeRenderer::destroyImage(int64_t imageID)
683 {
684     m_directlyCompositedImages.remove(imageID);
685 }
686
687 void WebLayerTreeRenderer::assignImageToLayer(GraphicsLayer* layer, int64_t imageID)
688 {
689     if (!imageID) {
690         layer->setContentsToMedia(0);
691         return;
692     }
693
694     HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID);
695     ASSERT(it != m_directlyCompositedImages.end());
696     layer->setContentsToMedia(it->second.get());
697 }
698
699 void WebLayerTreeRenderer::commitTileOperations()
700 {
701     HashSet<RefPtr<LayerBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
702     for (HashSet<RefPtr<LayerBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it)
703         (*it)->commitTileOperations(m_textureMapper.get());
704
705     m_backingStoresWithPendingBuffers.clear();
706 }
707
708 void WebLayerTreeRenderer::flushLayerChanges()
709 {
710     m_renderedContentsScrollPosition = m_pendingRenderedContentsScrollPosition;
711
712     // Since the frame has now been rendered, we can safely unlock the animations until the next layout.
713     setAnimationsLocked(false);
714
715     m_rootLayer->syncCompositingState(FloatRect());
716
717     commitTileOperations();
718
719     // The pending tiles state is on its way for the screen, tell the web process to render the next one.
720     callOnMainThread(bind(&WebLayerTreeRenderer::renderNextFrame, this));
721 }
722
723 void WebLayerTreeRenderer::renderNextFrame()
724 {
725     if (m_layerTreeCoordinatorProxy)
726         m_layerTreeCoordinatorProxy->renderNextFrame();
727 }
728
729 void WebLayerTreeRenderer::ensureRootLayer()
730 {
731     if (m_rootLayer)
732         return;
733
734 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
735     createTextureMapper();
736 #else
737     if (!m_textureMapper) {
738         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
739         static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
740     }
741 #endif
742
743     m_rootLayer = createLayer(InvalidWebLayerID);
744     m_rootLayer->setMasksToBounds(false);
745     m_rootLayer->setDrawsContent(false);
746     m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
747
748     // The root layer should not have zero size, or it would be optimized out.
749     m_rootLayer->setSize(FloatSize(1.0, 1.0));
750     toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
751 }
752
753 void WebLayerTreeRenderer::syncRemoteContent()
754 {
755     // We enqueue messages and execute them during paint, as they require an active GL context.
756     ensureRootLayer();
757
758     for (size_t i = 0; i < m_renderQueue.size(); ++i)
759         m_renderQueue[i]();
760
761     m_renderQueue.clear();
762 }
763
764 void WebLayerTreeRenderer::purgeGLResources()
765 {
766     TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
767
768     if (layer)
769         layer->clearBackingStoresRecursive();
770
771     m_directlyCompositedImages.clear();
772 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
773     m_surfaceBackingStores.clear();
774 #endif
775
776     m_rootLayer->removeAllChildren();
777     m_rootLayer.clear();
778     m_rootLayerID = InvalidWebLayerID;
779     m_layers.clear();
780     m_fixedLayers.clear();
781 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
782     m_scrollingContentsLayers.clear();
783 #endif
784     m_textureMapper.clear();
785     m_backingStoresWithPendingBuffers.clear();
786
787     setActive(false);
788
789     callOnMainThread(bind(&WebLayerTreeRenderer::purgeBackingStores, this));
790 }
791
792 void WebLayerTreeRenderer::setLayerAnimations(WebLayerID id, const GraphicsLayerAnimations& animations)
793 {
794     GraphicsLayerTextureMapper* layer = toGraphicsLayerTextureMapper(layerByID(id));
795     if (!layer)
796         return;
797     layer->setAnimations(animations);
798 }
799
800 void WebLayerTreeRenderer::setAnimationsLocked(bool locked)
801 {
802     m_animationsLocked = locked;
803 }
804
805 void WebLayerTreeRenderer::purgeBackingStores()
806 {
807     if (m_layerTreeCoordinatorProxy)
808         m_layerTreeCoordinatorProxy->purgeBackingStores();
809 }
810
811 void WebLayerTreeRenderer::detach()
812 {
813 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
814     m_renderQueue.clear();
815 #endif
816     m_layerTreeCoordinatorProxy = 0;
817 }
818
819 void WebLayerTreeRenderer::appendUpdate(const Function<void()>& function)
820 {
821     if (!m_isActive)
822         return;
823
824     m_renderQueue.append(function);
825 }
826
827 void WebLayerTreeRenderer::setActive(bool active)
828 {
829     if (m_isActive == active)
830         return;
831
832     // Have to clear render queue in both cases.
833     // If there are some updates in queue during activation then those updates are from previous instance of paint node
834     // and cannot be applied to the newly created instance.
835 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
836     if (!active)
837 #endif
838     m_renderQueue.clear();
839     m_isActive = active;
840 }
841
842 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
843 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
844 void WebLayerTreeRenderer::platformLayerChanged(WebCore::GraphicsLayer*, WebCore::PlatformLayer* oldPlatformLayer, WebCore::PlatformLayer* newPlatformLayer)
845 {
846     if (m_isActive)
847         renderNextFrame();
848 }
849 #endif
850
851 void WebLayerTreeRenderer::clearBackingStores()
852 {
853     LayerMap::iterator end = m_layers.end();
854     for(LayerMap::iterator it = m_layers.begin(); it != end; ++it)
855         toTextureMapperLayer(it->second)->clearBackingStore();
856
857     m_directlyCompositedImages.clear();
858     m_backingStoresWithPendingBuffers.clear();
859 }
860 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC)
861
862 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
863 void WebLayerTreeRenderer::showBackupTexture(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect)
864 {
865     if (!m_textureMapper)
866         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
867     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
868
869     if (!m_backupTexture
870         || !(m_backupTexture->isValid())
871         || m_backupTexture->size().width() != clipRect.width()
872         || m_backupTexture->size().height() != clipRect.height())
873         return;
874
875     m_textureMapper->beginPainting(1);
876     m_textureMapper->beginClip(TransformationMatrix(), clipRect);
877
878     IntSize viewportSize(clipRect.width(), clipRect.height());
879     const BitmapTextureGL* textureGL = static_cast<const BitmapTextureGL*>(m_backupTexture.get());
880     m_textureMapper->drawTexture(textureGL->id(), 0, viewportSize, clipRect, matrix, 1.0, viewportSize, false);
881
882     m_textureMapper->endClip();
883     m_textureMapper->endPainting();
884 }
885 #endif
886
887 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
888 void WebLayerTreeRenderer::createTextureMapper()
889 {
890     if (!m_textureMapper)
891         m_textureMapper = m_isGLMode ? TextureMapper::create(TextureMapper::OpenGLMode) : TextureMapper::create();
892
893     if (m_isGLMode)
894         ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
895     else
896         ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
897 }
898 #endif
899
900 } // namespace WebKit
901
902 #endif // USE(UI_SIDE_COMPOSITING)