Fix the issue that accelerated overflow scrolling become invisible
[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() - contentsLayer->position()));
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(FloatPoint(0, 0), scrollingLayer->size()));
393     const IntRect visibleRect(FloatRect(-contentsLayer->boundsOrigin().x(),
394                                         -contentsLayer->boundsOrigin().y(),
395                                         scrollingLayer->size().width(),
396                                         scrollingLayer->size().height()));
397
398
399     IntRect newVisibleRect = visibleRect;
400     newVisibleRect.moveBy(flooredIntPoint(offset));
401
402     if (newVisibleRect.x() < boundaryRect.x())
403         newVisibleRect.setX(boundaryRect.x());
404     if (contentLayerSize.width() - newVisibleRect.x() < boundaryRect.maxX())
405         newVisibleRect.setX(contentLayerSize.width() - boundaryRect.width());
406     if (newVisibleRect.y() < boundaryRect.y())
407         newVisibleRect.setY(boundaryRect.y());
408     if (contentLayerSize.height() - newVisibleRect.y() < boundaryRect.maxY())
409         newVisibleRect.setY(contentLayerSize.height() - boundaryRect.height());
410
411     if (visibleRect == newVisibleRect)
412         return false;
413
414     contentsLayer->setBoundsOrigin(FloatPoint(-newVisibleRect.x(), -newVisibleRect.y()));
415
416     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(id, visibleRect, offset), m_drawingAreaProxy->page()->pageID());
417
418     return true;
419 }
420
421 void WebLayerTreeRenderer::setVisibleContentsRectForScrollingContentsLayers(const WebCore::IntRect& visibleRect)
422 {
423     LayerMap::iterator end = m_scrollingContentsLayers.end();
424     for (LayerMap::iterator it = m_scrollingContentsLayers.begin(); it != end; ++it) {
425         GraphicsLayer* contentsLayer = it->second;
426         GraphicsLayer* scrollingLayer = contentsLayer ? contentsLayer->parent() : 0;
427         if (!scrollingLayer)
428             continue;
429
430         // FIXME: We might need to check if the each content layer is in viewport.
431         // Simply, we should find out a intersected rect between visibleRect and each scrollingLayer here.
432         const IntRect newVisibleRect(FloatRect(contentsLayer->boundsOrigin(), scrollingLayer->size()));
433
434         m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(it->first, newVisibleRect, WebCore::FloatPoint()), m_drawingAreaProxy->page()->pageID());
435     }
436 }
437 #endif
438
439 void WebLayerTreeRenderer::didChangeScrollPosition(const IntPoint& position)
440 {
441     m_pendingRenderedContentsScrollPosition = position;
442 }
443
444 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
445 void WebLayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer, int flags)
446 #else
447 void WebLayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer)
448 #endif
449 {
450     if (canvasSize.isEmpty() || !m_textureMapper)
451         return;
452
453 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
454     ensureLayer(id);
455     GraphicsLayer* layer = layerByID(id);
456
457     RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore;
458     SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(id);
459     if (it == m_surfaceBackingStores.end()) {
460         canvasBackingStore = TextureMapperSurfaceBackingStore::create();
461         m_surfaceBackingStores.set(id, canvasBackingStore);
462     } else
463         canvasBackingStore = it->second;
464
465 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
466     canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize, frontBuffer, flags);
467 #else
468     canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize, frontBuffer);
469 #endif
470     layer->setContentsToMedia(canvasBackingStore.get());
471 #endif
472 }
473
474 void WebLayerTreeRenderer::setLayerChildren(WebLayerID id, const Vector<WebLayerID>& childIDs)
475 {
476     ensureLayer(id);
477     LayerMap::iterator it = m_layers.find(id);
478     GraphicsLayer* layer = it->second;
479     Vector<GraphicsLayer*> children;
480
481     for (size_t i = 0; i < childIDs.size(); ++i) {
482         WebLayerID childID = childIDs[i];
483         GraphicsLayer* child = layerByID(childID);
484         if (!child) {
485             child = createLayer(childID).leakPtr();
486             m_layers.add(childID, child);
487         }
488         children.append(child);
489     }
490     layer->setChildren(children);
491 }
492
493 #if ENABLE(CSS_FILTERS)
494 void WebLayerTreeRenderer::setLayerFilters(WebLayerID id, const FilterOperations& filters)
495 {
496     ensureLayer(id);
497     LayerMap::iterator it = m_layers.find(id);
498     ASSERT(it != m_layers.end());
499
500     GraphicsLayer* layer = it->second;
501     layer->setFilters(filters);
502 }
503 #endif
504
505 void WebLayerTreeRenderer::setLayerState(WebLayerID id, const WebLayerInfo& layerInfo)
506 {
507     ensureLayer(id);
508     LayerMap::iterator it = m_layers.find(id);
509     ASSERT(it != m_layers.end());
510
511     GraphicsLayer* layer = it->second;
512
513     layer->setReplicatedByLayer(layerByID(layerInfo.replica));
514     layer->setMaskLayer(layerByID(layerInfo.mask));
515
516     layer->setPosition(layerInfo.pos);
517     layer->setSize(layerInfo.size);
518     layer->setTransform(layerInfo.transform);
519     layer->setAnchorPoint(layerInfo.anchorPoint);
520     layer->setChildrenTransform(layerInfo.childrenTransform);
521     layer->setBackfaceVisibility(layerInfo.backfaceVisible);
522     layer->setContentsOpaque(layerInfo.contentsOpaque);
523     layer->setContentsRect(layerInfo.contentsRect);
524     layer->setContentsToBackgroundColor(layerInfo.backgroundColor);
525     layer->setDrawsContent(layerInfo.drawsContent);
526     layer->setContentsVisible(layerInfo.contentsVisible);
527     toGraphicsLayerTextureMapper(layer)->setFixedToViewport(layerInfo.fixedToViewport);
528
529     if (layerInfo.fixedToViewport)
530         m_fixedLayers.add(id, layer);
531     else
532         m_fixedLayers.remove(id);
533
534 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
535     if (layerInfo.isScrollingContentsLayer) {
536         LayerMap::iterator it = m_scrollingContentsLayers.find(id);
537         if (it == m_scrollingContentsLayers.end() || (layer->boundsOrigin() != layerInfo.boundsOrigin)) {
538             layer->setBoundsOrigin(layerInfo.boundsOrigin);
539             GraphicsLayer* scrollingLayer = layerByID(layerInfo.parent);
540             if (scrollingLayer) {
541                 const IntRect newVisibleRect(FloatRect(layer->boundsOrigin(), scrollingLayer->size()));
542                 m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(id, newVisibleRect, WebCore::FloatPoint()), m_drawingAreaProxy->page()->pageID());
543             }
544         }
545         m_scrollingContentsLayers.add(id, layer);
546     }
547     else
548         m_scrollingContentsLayers.remove(id);
549 #endif
550 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_SCROLLBAR)
551     layer->setIsScrollbar(layerInfo.isScrollbar);
552 #endif
553
554     assignImageToLayer(layer, layerInfo.imageBackingStoreID);
555
556     // Never make the root layer clip.
557     layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds);
558     layer->setOpacity(layerInfo.opacity);
559     layer->setPreserves3D(layerInfo.preserves3D);
560     if (layerInfo.isRootLayer && m_rootLayerID != id)
561         setRootLayerID(id);
562 }
563
564 void WebLayerTreeRenderer::deleteLayer(WebLayerID layerID)
565 {
566     GraphicsLayer* layer = layerByID(layerID);
567     if (!layer)
568         return;
569
570 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
571     LOG(AcceleratedCompositing, "[UI ] delete layer %u @WebLayerTreeRenderer::deleteLayer \n", layerID);
572 #endif
573
574     layer->removeFromParent();
575     m_layers.remove(layerID);
576     m_fixedLayers.remove(layerID);
577 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
578     m_scrollingContentsLayers.remove(layerID);
579 #endif
580 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
581     m_surfaceBackingStores.remove(layerID);
582 #endif
583     delete layer;
584 }
585
586
587 void WebLayerTreeRenderer::ensureLayer(WebLayerID id)
588 {
589     // We have to leak the new layer's pointer and manage it ourselves,
590     // because OwnPtr is not copyable.
591     if (m_layers.find(id) == m_layers.end())
592         m_layers.add(id, createLayer(id).leakPtr());
593 }
594
595 void WebLayerTreeRenderer::setRootLayerID(WebLayerID layerID)
596 {
597     if (layerID == m_rootLayerID)
598         return;
599
600     m_rootLayerID = layerID;
601
602     m_rootLayer->removeAllChildren();
603
604     if (!layerID)
605         return;
606
607     GraphicsLayer* layer = layerByID(layerID);
608     if (!layer)
609         return;
610
611     m_rootLayer->addChild(layer);
612 }
613
614 PassRefPtr<LayerBackingStore> WebLayerTreeRenderer::getBackingStore(WebLayerID id)
615 {
616     TextureMapperLayer* layer = toTextureMapperLayer(layerByID(id));
617     ASSERT(layer);
618     RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get());
619     if (!backingStore) {
620         backingStore = LayerBackingStore::create();
621         layer->setBackingStore(backingStore.get());
622     }
623     ASSERT(backingStore);
624     return backingStore;
625 }
626
627 void WebLayerTreeRenderer::createTile(WebLayerID layerID, int tileID, float scale)
628 {
629 #if OS(TIZEN)
630     if (!layerByID(layerID))
631         return;
632 #endif
633
634     getBackingStore(layerID)->createTile(tileID, scale);
635 }
636
637 void WebLayerTreeRenderer::removeBackingStoreIfNeeded(WebLayerID layerID)
638 {
639     TextureMapperLayer* layer = toTextureMapperLayer(layerByID(layerID));
640     ASSERT(layer);
641     RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get());
642     ASSERT(backingStore);
643     if (backingStore->isEmpty())
644         layer->setBackingStore(0);
645 }
646
647 void WebLayerTreeRenderer::removeTile(WebLayerID layerID, int tileID)
648 {
649 #if OS(TIZEN)
650     // Check whether composited graphics layer already been detached
651     GraphicsLayer* pGraphicsLayer = layerByID(layerID);
652     if (!pGraphicsLayer)
653         return;
654 #endif
655     getBackingStore(layerID)->removeTile(tileID);
656     removeBackingStoreIfNeeded(layerID);
657 }
658
659 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
660 void WebLayerTreeRenderer::updateTileWithUpdateInfo(WebLayerID layerID, int tileID, const TileUpdate& update)
661 {
662     updateTile(layerID, tileID, update);
663 }
664 #endif
665
666 void WebLayerTreeRenderer::updateTile(WebLayerID layerID, int tileID, const TileUpdate& update)
667 {
668 #if OS(TIZEN)
669     if (!layerByID(layerID))
670         return;
671 #endif
672
673     RefPtr<LayerBackingStore> backingStore = getBackingStore(layerID);
674     backingStore->updateTile(tileID, update.sourceRect, update.targetRect, update.surface, update.offset);
675     m_backingStoresWithPendingBuffers.add(backingStore);
676 }
677
678 void WebLayerTreeRenderer::createImage(int64_t imageID, PassRefPtr<ShareableBitmap> weakBitmap)
679 {
680     RefPtr<ShareableBitmap> bitmap = weakBitmap;
681     RefPtr<TextureMapperTiledBackingStore> backingStore = TextureMapperTiledBackingStore::create();
682     m_directlyCompositedImages.set(imageID, backingStore);
683     backingStore->updateContents(m_textureMapper.get(), bitmap->createImage().get());
684 }
685
686 void WebLayerTreeRenderer::destroyImage(int64_t imageID)
687 {
688     m_directlyCompositedImages.remove(imageID);
689 }
690
691 void WebLayerTreeRenderer::assignImageToLayer(GraphicsLayer* layer, int64_t imageID)
692 {
693     if (!imageID) {
694         layer->setContentsToMedia(0);
695         return;
696     }
697
698     HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID);
699     ASSERT(it != m_directlyCompositedImages.end());
700     layer->setContentsToMedia(it->second.get());
701 }
702
703 void WebLayerTreeRenderer::commitTileOperations()
704 {
705     HashSet<RefPtr<LayerBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
706     for (HashSet<RefPtr<LayerBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it)
707         (*it)->commitTileOperations(m_textureMapper.get());
708
709     m_backingStoresWithPendingBuffers.clear();
710 }
711
712 void WebLayerTreeRenderer::flushLayerChanges()
713 {
714     m_renderedContentsScrollPosition = m_pendingRenderedContentsScrollPosition;
715
716     // Since the frame has now been rendered, we can safely unlock the animations until the next layout.
717     setAnimationsLocked(false);
718
719     m_rootLayer->syncCompositingState(FloatRect());
720
721     commitTileOperations();
722
723     // The pending tiles state is on its way for the screen, tell the web process to render the next one.
724     callOnMainThread(bind(&WebLayerTreeRenderer::renderNextFrame, this));
725 }
726
727 void WebLayerTreeRenderer::renderNextFrame()
728 {
729     if (m_layerTreeCoordinatorProxy)
730         m_layerTreeCoordinatorProxy->renderNextFrame();
731 }
732
733 void WebLayerTreeRenderer::ensureRootLayer()
734 {
735     if (m_rootLayer)
736         return;
737
738 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
739     createTextureMapper();
740 #else
741     if (!m_textureMapper) {
742         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
743         static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
744     }
745 #endif
746
747     m_rootLayer = createLayer(InvalidWebLayerID);
748     m_rootLayer->setMasksToBounds(false);
749     m_rootLayer->setDrawsContent(false);
750     m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
751
752     // The root layer should not have zero size, or it would be optimized out.
753     m_rootLayer->setSize(FloatSize(1.0, 1.0));
754     toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
755 }
756
757 void WebLayerTreeRenderer::syncRemoteContent()
758 {
759     // We enqueue messages and execute them during paint, as they require an active GL context.
760     ensureRootLayer();
761
762     for (size_t i = 0; i < m_renderQueue.size(); ++i)
763         m_renderQueue[i]();
764
765     m_renderQueue.clear();
766 }
767
768 void WebLayerTreeRenderer::purgeGLResources()
769 {
770     TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
771
772     if (layer)
773         layer->clearBackingStoresRecursive();
774
775     m_directlyCompositedImages.clear();
776 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
777     m_surfaceBackingStores.clear();
778 #endif
779
780     m_rootLayer->removeAllChildren();
781     m_rootLayer.clear();
782     m_rootLayerID = InvalidWebLayerID;
783     m_layers.clear();
784     m_fixedLayers.clear();
785 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
786     m_scrollingContentsLayers.clear();
787 #endif
788     m_textureMapper.clear();
789     m_backingStoresWithPendingBuffers.clear();
790
791     setActive(false);
792
793     callOnMainThread(bind(&WebLayerTreeRenderer::purgeBackingStores, this));
794 }
795
796 void WebLayerTreeRenderer::setLayerAnimations(WebLayerID id, const GraphicsLayerAnimations& animations)
797 {
798     GraphicsLayerTextureMapper* layer = toGraphicsLayerTextureMapper(layerByID(id));
799     if (!layer)
800         return;
801     layer->setAnimations(animations);
802 }
803
804 void WebLayerTreeRenderer::setAnimationsLocked(bool locked)
805 {
806     m_animationsLocked = locked;
807 }
808
809 void WebLayerTreeRenderer::purgeBackingStores()
810 {
811     if (m_layerTreeCoordinatorProxy)
812         m_layerTreeCoordinatorProxy->purgeBackingStores();
813 }
814
815 void WebLayerTreeRenderer::detach()
816 {
817 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
818     m_renderQueue.clear();
819 #endif
820     m_layerTreeCoordinatorProxy = 0;
821 }
822
823 void WebLayerTreeRenderer::appendUpdate(const Function<void()>& function)
824 {
825     if (!m_isActive)
826         return;
827
828     m_renderQueue.append(function);
829 }
830
831 void WebLayerTreeRenderer::setActive(bool active)
832 {
833     if (m_isActive == active)
834         return;
835
836     // Have to clear render queue in both cases.
837     // If there are some updates in queue during activation then those updates are from previous instance of paint node
838     // and cannot be applied to the newly created instance.
839 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
840     if (!active)
841 #endif
842     m_renderQueue.clear();
843     m_isActive = active;
844 }
845
846 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
847 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
848 void WebLayerTreeRenderer::platformLayerChanged(WebCore::GraphicsLayer*, WebCore::PlatformLayer* oldPlatformLayer, WebCore::PlatformLayer* newPlatformLayer)
849 {
850     if (m_isActive)
851         renderNextFrame();
852 }
853 #endif
854
855 void WebLayerTreeRenderer::clearBackingStores()
856 {
857     LayerMap::iterator end = m_layers.end();
858     for(LayerMap::iterator it = m_layers.begin(); it != end; ++it)
859         toTextureMapperLayer(it->second)->clearBackingStore();
860
861     m_directlyCompositedImages.clear();
862     m_backingStoresWithPendingBuffers.clear();
863 }
864 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC)
865
866 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
867 void WebLayerTreeRenderer::showBackupTexture(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect)
868 {
869     if (!m_textureMapper)
870         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
871     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
872
873     if (!m_backupTexture
874         || !(m_backupTexture->isValid())
875         || m_backupTexture->size().width() != clipRect.width()
876         || m_backupTexture->size().height() != clipRect.height())
877         return;
878
879     m_textureMapper->beginPainting(1);
880     m_textureMapper->beginClip(TransformationMatrix(), clipRect);
881
882     IntSize viewportSize(clipRect.width(), clipRect.height());
883     const BitmapTextureGL* textureGL = static_cast<const BitmapTextureGL*>(m_backupTexture.get());
884     m_textureMapper->drawTexture(textureGL->id(), 0, viewportSize, clipRect, matrix, 1.0, viewportSize, false);
885
886     m_textureMapper->endClip();
887     m_textureMapper->endPainting();
888 }
889 #endif
890
891 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
892 void WebLayerTreeRenderer::createTextureMapper()
893 {
894     if (!m_textureMapper)
895         m_textureMapper = m_isGLMode ? TextureMapper::create(TextureMapper::OpenGLMode) : TextureMapper::create();
896
897     if (m_isGLMode)
898         ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
899     else
900         ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
901 }
902 #endif
903
904 } // namespace WebKit
905
906 #endif // USE(UI_SIDE_COMPOSITING)