2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
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.
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.
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.
22 #if USE(UI_SIDE_COMPOSITING)
24 #include "WebLayerTreeRenderer.h"
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>
39 #include <WebCore/Logging.h>
40 #include <wtf/Atomics.h>
41 #include <wtf/MainThread.h>
43 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
44 #include "LayerTreeCoordinatorMessages.h"
45 #include "TextureMapperGL.h"
50 using namespace WebCore;
52 template<class T> class MainThreadGuardedInvoker {
54 static void call(PassRefPtr<T> objectToGuard, const Function<void()>& function)
56 MainThreadGuardedInvoker<T>* invoker = new MainThreadGuardedInvoker<T>(objectToGuard, function);
57 callOnMainThread(invoke, invoker);
61 MainThreadGuardedInvoker(PassRefPtr<T> object, const Function<void()>& newFunction)
62 : objectToGuard(object)
63 , function(newFunction)
67 RefPtr<T> objectToGuard;
68 Function<void()> function;
69 static void invoke(void* data)
71 MainThreadGuardedInvoker<T>* invoker = static_cast<MainThreadGuardedInvoker<T>*>(data);
77 void WebLayerTreeRenderer::callOnMainThread(const Function<void()>& function)
82 MainThreadGuardedInvoker<WebLayerTreeRenderer>::call(this, function);
85 static FloatPoint boundedScrollPosition(const FloatPoint& scrollPosition, const FloatRect& visibleContentRect, const FloatSize& contentSize)
87 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
88 float scrollPositionX = std::max(scrollPosition.x(), 0.0f);
89 scrollPositionX = std::min(scrollPositionX, contentSize.width());
91 float scrollPositionY = std::max(scrollPosition.y(), 0.0f);
92 scrollPositionY = std::min(scrollPositionY, contentSize.height());
94 // Prevent negative scroll position.
95 scrollPositionX = std::max(scrollPositionX, 0.0f);
96 scrollPositionY = std::max(scrollPositionY, 0.0f);
98 float scrollPositionX = std::max(scrollPosition.x(), 0.0f);
99 scrollPositionX = std::min(scrollPositionX, contentSize.width() - visibleContentRect.width());
101 float scrollPositionY = std::max(scrollPosition.y(), 0.0f);
102 scrollPositionY = std::min(scrollPositionY, contentSize.height() - visibleContentRect.height());
105 return FloatPoint(scrollPositionX, scrollPositionY);
108 WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeCoordinatorProxy* layerTreeCoordinatorProxy)
110 , m_layerTreeCoordinatorProxy(layerTreeCoordinatorProxy)
111 , m_rootLayerID(InvalidWebLayerID)
113 , m_animationsLocked(false)
114 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
118 , m_updateViewportTimer(RunLoop::current(), this, &WebLayerTreeRenderer::updateViewportFired)
123 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
124 WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeCoordinatorProxy* layerTreeCoordinatorProxy, DrawingAreaProxy* drawingAreaProxy, bool isGLMode)
126 , m_layerTreeCoordinatorProxy(layerTreeCoordinatorProxy)
127 , m_rootLayerID(InvalidWebLayerID)
129 , m_animationsLocked(false)
130 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
133 , m_drawingAreaProxy(drawingAreaProxy)
134 , m_isGLMode(isGLMode)
136 , m_updateViewportTimer(RunLoop::current(), this, &WebLayerTreeRenderer::updateViewportFired)
142 WebLayerTreeRenderer::~WebLayerTreeRenderer()
144 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
145 if (m_backupTexture && m_backupTexture->isValid()) {
146 m_backupTexture.release();
151 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
152 deleteAllValues(m_layers);
156 PassOwnPtr<GraphicsLayer> WebLayerTreeRenderer::createLayer(WebLayerID layerID)
158 GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this);
159 TextureMapperLayer* layer = toTextureMapperLayer(newLayer);
160 layer->setShouldUpdateBackingStoreFromLayer(false);
162 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
163 LOG(AcceleratedCompositing, "[UI ] create layer %u @WebLayerTreeRenderer::createLayer \n", layerID);
166 return adoptPtr(newLayer);
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)
172 if (!m_textureMapper)
173 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
174 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
176 adjustPositionForFixedLayers();
177 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
178 adjustPositionForOverflowLayers();
181 GraphicsLayer* currentRootLayer = rootLayer();
182 if (!currentRootLayer)
185 TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
189 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
190 static_cast<TextureMapperGL*>(m_textureMapper.get())->setAngle(m_angle);
193 if (!m_backupTexture || m_backupTexture->size() != IntSize(clipRect.width(), clipRect.height()))
194 m_backupTexture = m_textureMapper->acquireTextureFromPool(IntSize(clipRect.width(), clipRect.height()));
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);
203 if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
204 currentRootLayer->setOpacity(opacity);
205 currentRootLayer->setTransform(matrix);
206 currentRootLayer->syncCompositingStateForThisLayerOnly();
209 glClearColor(bgColor.red(), bgColor.green(), bgColor.blue(), bgColor.alpha());
210 glClear(GL_COLOR_BUFFER_BIT);
212 #if ENABLE(TIZEN_TEXTURE_MAPPER_CULLER)
213 layer->paintWithCuller(clipRect);
218 m_textureMapper->endClip();
219 m_textureMapper->endPainting();
220 m_textureMapper->unbindSurface();
222 if (layer->descendantsOrSelfHaveRunningAnimations()) {
224 m_updateViewportTimer.startOneShot(0);
226 callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this));
232 void WebLayerTreeRenderer::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const WebCore::Color& backgroundColor, TextureMapper::PaintFlags PaintFlags)
234 if (!m_textureMapper)
235 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
236 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
238 adjustPositionForFixedLayers();
239 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
240 adjustPositionForOverflowLayers();
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);
251 TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
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);
261 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
262 static_cast<TextureMapperGL*>(m_textureMapper.get())->setAngle(m_angle);
265 layer->setTextureMapper(m_textureMapper.get());
266 if (!m_animationsLocked)
267 layer->applyAnimationsRecursively();
268 m_textureMapper->beginPainting(PaintFlags);
269 m_textureMapper->beginClip(TransformationMatrix(), clipRect);
271 m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), backgroundColor);
273 if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
274 currentRootLayer->setOpacity(opacity);
275 currentRootLayer->setTransform(matrix);
276 currentRootLayer->syncCompositingStateForThisLayerOnly();
279 #if ENABLE(TIZEN_TEXTURE_MAPPER_CULLER)
280 layer->paintWithCuller(clipRect);
285 m_textureMapper->endClip();
286 m_textureMapper->endPainting();
287 if (layer->descendantsOrSelfHaveRunningAnimations()) {
289 m_updateViewportTimer.startOneShot(0);
291 callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this));
296 #if PLATFORM(QT) || PLATFORM(EFL)
297 void WebLayerTreeRenderer::paintToGraphicsContext(BackingStore::PlatformGraphicsContext painter, const WebCore::Color& backgroundColor)
299 if (!m_textureMapper)
300 m_textureMapper = TextureMapper::create();
301 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
303 TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
308 GraphicsContext graphicsContext(painter);
309 m_textureMapper->setGraphicsContext(&graphicsContext);
310 m_textureMapper->beginPainting();
311 m_textureMapper->drawSolidColor(graphicsContext.clipBounds(), TransformationMatrix(), backgroundColor);
313 m_textureMapper->endPainting();
314 m_textureMapper->setGraphicsContext(0);
318 void WebLayerTreeRenderer::setContentsSize(const WebCore::FloatSize& contentsSize)
320 m_contentsSize = contentsSize;
323 void WebLayerTreeRenderer::setVisibleContentsRect(const IntRect& rect, float scale, const WebCore::FloatPoint& accurateVisibleContentsPosition)
325 m_visibleContentsRect = rect;
326 m_contentsScale = scale;
327 m_accurateVisibleContentsPosition = accurateVisibleContentsPosition;
331 void WebLayerTreeRenderer::updateViewportFired()
333 callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this));
337 void WebLayerTreeRenderer::updateViewport()
339 if (m_layerTreeCoordinatorProxy)
340 m_layerTreeCoordinatorProxy->updateViewport();
343 void WebLayerTreeRenderer::adjustPositionForFixedLayers()
345 if (m_fixedLayers.isEmpty())
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;
355 LayerMap::iterator end = m_fixedLayers.end();
356 for (LayerMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
357 toTextureMapperLayer(it->second)->setScrollPositionDeltaIfNeeded(delta);
360 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
361 void WebLayerTreeRenderer::adjustPositionForOverflowLayers()
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)
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()));
376 textureMapperLayer->setScrollPositionDeltaIfNeeded(FloatSize(contentsLayer->boundsOrigin() - contentsLayer->position()));
380 bool WebLayerTreeRenderer::setOffset(const WebLayerID id, const FloatPoint& offset)
382 LayerMap::iterator it = m_scrollingContentsLayers.find(id);
383 if (it == m_scrollingContentsLayers.end())
386 GraphicsLayer* contentsLayer = it->second;
387 GraphicsLayer* scrollingLayer = contentsLayer ? contentsLayer->parent() : 0;
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()));
399 IntRect newVisibleRect = visibleRect;
400 newVisibleRect.moveBy(flooredIntPoint(offset));
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());
411 if (visibleRect == newVisibleRect)
414 contentsLayer->setBoundsOrigin(FloatPoint(-newVisibleRect.x(), -newVisibleRect.y()));
416 m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(id, visibleRect, offset), m_drawingAreaProxy->page()->pageID());
421 void WebLayerTreeRenderer::setVisibleContentsRectForScrollingContentsLayers(const WebCore::IntRect& visibleRect)
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;
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()));
434 m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRectAndTrajectoryVectorForLayer(it->first, newVisibleRect, WebCore::FloatPoint()), m_drawingAreaProxy->page()->pageID());
439 void WebLayerTreeRenderer::didChangeScrollPosition(const IntPoint& position)
441 m_pendingRenderedContentsScrollPosition = position;
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)
447 void WebLayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer)
450 if (canvasSize.isEmpty() || !m_textureMapper)
453 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
455 GraphicsLayer* layer = layerByID(id);
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);
463 canvasBackingStore = it->second;
465 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
466 canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize, frontBuffer, flags);
468 canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize, frontBuffer);
470 layer->setContentsToMedia(canvasBackingStore.get());
474 void WebLayerTreeRenderer::setLayerChildren(WebLayerID id, const Vector<WebLayerID>& childIDs)
477 LayerMap::iterator it = m_layers.find(id);
478 GraphicsLayer* layer = it->second;
479 Vector<GraphicsLayer*> children;
481 for (size_t i = 0; i < childIDs.size(); ++i) {
482 WebLayerID childID = childIDs[i];
483 GraphicsLayer* child = layerByID(childID);
485 child = createLayer(childID).leakPtr();
486 m_layers.add(childID, child);
488 children.append(child);
490 layer->setChildren(children);
493 #if ENABLE(CSS_FILTERS)
494 void WebLayerTreeRenderer::setLayerFilters(WebLayerID id, const FilterOperations& filters)
497 LayerMap::iterator it = m_layers.find(id);
498 ASSERT(it != m_layers.end());
500 GraphicsLayer* layer = it->second;
501 layer->setFilters(filters);
505 void WebLayerTreeRenderer::setLayerState(WebLayerID id, const WebLayerInfo& layerInfo)
508 LayerMap::iterator it = m_layers.find(id);
509 ASSERT(it != m_layers.end());
511 GraphicsLayer* layer = it->second;
513 layer->setReplicatedByLayer(layerByID(layerInfo.replica));
514 layer->setMaskLayer(layerByID(layerInfo.mask));
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);
529 if (layerInfo.fixedToViewport)
530 m_fixedLayers.add(id, layer);
532 m_fixedLayers.remove(id);
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());
545 m_scrollingContentsLayers.add(id, layer);
548 m_scrollingContentsLayers.remove(id);
550 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_SCROLLBAR)
551 layer->setIsScrollbar(layerInfo.isScrollbar);
554 assignImageToLayer(layer, layerInfo.imageBackingStoreID);
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)
564 void WebLayerTreeRenderer::deleteLayer(WebLayerID layerID)
566 GraphicsLayer* layer = layerByID(layerID);
570 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
571 LOG(AcceleratedCompositing, "[UI ] delete layer %u @WebLayerTreeRenderer::deleteLayer \n", layerID);
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);
580 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
581 m_surfaceBackingStores.remove(layerID);
587 void WebLayerTreeRenderer::ensureLayer(WebLayerID id)
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());
595 void WebLayerTreeRenderer::setRootLayerID(WebLayerID layerID)
597 if (layerID == m_rootLayerID)
600 m_rootLayerID = layerID;
602 m_rootLayer->removeAllChildren();
607 GraphicsLayer* layer = layerByID(layerID);
611 m_rootLayer->addChild(layer);
614 PassRefPtr<LayerBackingStore> WebLayerTreeRenderer::getBackingStore(WebLayerID id)
616 TextureMapperLayer* layer = toTextureMapperLayer(layerByID(id));
618 RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get());
620 backingStore = LayerBackingStore::create();
621 layer->setBackingStore(backingStore.get());
623 ASSERT(backingStore);
627 void WebLayerTreeRenderer::createTile(WebLayerID layerID, int tileID, float scale)
630 if (!layerByID(layerID))
634 getBackingStore(layerID)->createTile(tileID, scale);
637 void WebLayerTreeRenderer::removeBackingStoreIfNeeded(WebLayerID layerID)
639 TextureMapperLayer* layer = toTextureMapperLayer(layerByID(layerID));
641 RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get());
642 ASSERT(backingStore);
643 if (backingStore->isEmpty())
644 layer->setBackingStore(0);
647 void WebLayerTreeRenderer::removeTile(WebLayerID layerID, int tileID)
650 // Check whether composited graphics layer already been detached
651 GraphicsLayer* pGraphicsLayer = layerByID(layerID);
655 getBackingStore(layerID)->removeTile(tileID);
656 removeBackingStoreIfNeeded(layerID);
659 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
660 void WebLayerTreeRenderer::updateTileWithUpdateInfo(WebLayerID layerID, int tileID, const TileUpdate& update)
662 updateTile(layerID, tileID, update);
666 void WebLayerTreeRenderer::updateTile(WebLayerID layerID, int tileID, const TileUpdate& update)
669 if (!layerByID(layerID))
673 RefPtr<LayerBackingStore> backingStore = getBackingStore(layerID);
674 backingStore->updateTile(tileID, update.sourceRect, update.targetRect, update.surface, update.offset);
675 m_backingStoresWithPendingBuffers.add(backingStore);
678 void WebLayerTreeRenderer::createImage(int64_t imageID, PassRefPtr<ShareableBitmap> weakBitmap)
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());
686 void WebLayerTreeRenderer::destroyImage(int64_t imageID)
688 m_directlyCompositedImages.remove(imageID);
691 void WebLayerTreeRenderer::assignImageToLayer(GraphicsLayer* layer, int64_t imageID)
694 layer->setContentsToMedia(0);
698 HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID);
699 ASSERT(it != m_directlyCompositedImages.end());
700 layer->setContentsToMedia(it->second.get());
703 void WebLayerTreeRenderer::commitTileOperations()
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());
709 m_backingStoresWithPendingBuffers.clear();
712 void WebLayerTreeRenderer::flushLayerChanges()
714 m_renderedContentsScrollPosition = m_pendingRenderedContentsScrollPosition;
716 // Since the frame has now been rendered, we can safely unlock the animations until the next layout.
717 setAnimationsLocked(false);
719 m_rootLayer->syncCompositingState(FloatRect());
721 commitTileOperations();
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));
727 void WebLayerTreeRenderer::renderNextFrame()
729 if (m_layerTreeCoordinatorProxy)
730 m_layerTreeCoordinatorProxy->renderNextFrame();
733 void WebLayerTreeRenderer::ensureRootLayer()
738 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
739 createTextureMapper();
741 if (!m_textureMapper) {
742 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
743 static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
747 m_rootLayer = createLayer(InvalidWebLayerID);
748 m_rootLayer->setMasksToBounds(false);
749 m_rootLayer->setDrawsContent(false);
750 m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
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());
757 void WebLayerTreeRenderer::syncRemoteContent()
759 // We enqueue messages and execute them during paint, as they require an active GL context.
762 for (size_t i = 0; i < m_renderQueue.size(); ++i)
765 m_renderQueue.clear();
768 void WebLayerTreeRenderer::purgeGLResources()
770 TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
773 layer->clearBackingStoresRecursive();
775 m_directlyCompositedImages.clear();
776 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
777 m_surfaceBackingStores.clear();
780 m_rootLayer->removeAllChildren();
782 m_rootLayerID = InvalidWebLayerID;
784 m_fixedLayers.clear();
785 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
786 m_scrollingContentsLayers.clear();
788 m_textureMapper.clear();
789 m_backingStoresWithPendingBuffers.clear();
793 callOnMainThread(bind(&WebLayerTreeRenderer::purgeBackingStores, this));
796 void WebLayerTreeRenderer::setLayerAnimations(WebLayerID id, const GraphicsLayerAnimations& animations)
798 GraphicsLayerTextureMapper* layer = toGraphicsLayerTextureMapper(layerByID(id));
801 layer->setAnimations(animations);
804 void WebLayerTreeRenderer::setAnimationsLocked(bool locked)
806 m_animationsLocked = locked;
809 void WebLayerTreeRenderer::purgeBackingStores()
811 if (m_layerTreeCoordinatorProxy)
812 m_layerTreeCoordinatorProxy->purgeBackingStores();
815 void WebLayerTreeRenderer::detach()
817 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
818 m_renderQueue.clear();
820 m_layerTreeCoordinatorProxy = 0;
823 void WebLayerTreeRenderer::appendUpdate(const Function<void()>& function)
828 m_renderQueue.append(function);
831 void WebLayerTreeRenderer::setActive(bool active)
833 if (m_isActive == active)
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)
842 m_renderQueue.clear();
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)
855 void WebLayerTreeRenderer::clearBackingStores()
857 LayerMap::iterator end = m_layers.end();
858 for(LayerMap::iterator it = m_layers.begin(); it != end; ++it)
859 toTextureMapperLayer(it->second)->clearBackingStore();
861 m_directlyCompositedImages.clear();
862 m_backingStoresWithPendingBuffers.clear();
864 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC)
866 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
867 void WebLayerTreeRenderer::showBackupTexture(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect)
869 if (!m_textureMapper)
870 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
871 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
874 || !(m_backupTexture->isValid())
875 || m_backupTexture->size().width() != clipRect.width()
876 || m_backupTexture->size().height() != clipRect.height())
879 m_textureMapper->beginPainting(1);
880 m_textureMapper->beginClip(TransformationMatrix(), clipRect);
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);
886 m_textureMapper->endClip();
887 m_textureMapper->endPainting();
891 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
892 void WebLayerTreeRenderer::createTextureMapper()
894 if (!m_textureMapper)
895 m_textureMapper = m_isGLMode ? TextureMapper::create(TextureMapper::OpenGLMode) : TextureMapper::create();
898 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
900 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
904 } // namespace WebKit
906 #endif // USE(UI_SIDE_COMPOSITING)