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