summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/CoordinatedGraphics
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/CoordinatedGraphics')
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp163
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.h79
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp188
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h99
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in40
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp515
-rw-r--r--Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.h156
7 files changed, 1240 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp b/Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp
new file mode 100644
index 000000000..84f6ebd2f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp
@@ -0,0 +1,163 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "CoordinatedBackingStore.h"
+
+#if USE(COORDINATED_GRAPHICS)
+#include "GraphicsLayer.h"
+#include "ShareableSurface.h"
+#include "TextureMapper.h"
+#include "TextureMapperGL.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void CoordinatedBackingStoreTile::swapBuffers(WebCore::TextureMapper* textureMapper)
+{
+ if (!m_surface)
+ return;
+
+ FloatRect targetRect(m_targetRect);
+ targetRect.scale(1. / m_scale);
+ bool shouldReset = false;
+ if (targetRect != rect()) {
+ setRect(targetRect);
+ shouldReset = true;
+ }
+ RefPtr<BitmapTexture> texture = this->texture();
+ if (!texture) {
+ texture = textureMapper->createTexture();
+ setTexture(texture.get());
+ shouldReset = true;
+ }
+
+ if (shouldReset)
+ texture->reset(m_targetRect.size(), m_surface->flags() & ShareableBitmap::SupportsAlpha ? BitmapTexture::SupportsAlpha : 0);
+
+ m_surface->copyToTexture(texture, m_sourceRect, m_surfaceOffset);
+ m_surface.clear();
+}
+
+void CoordinatedBackingStoreTile::setBackBuffer(const IntRect& targetRect, const IntRect& sourceRect, PassRefPtr<ShareableSurface> buffer, const IntPoint& offset)
+{
+ m_sourceRect = sourceRect;
+ m_targetRect = targetRect;
+ m_surfaceOffset = offset;
+ m_surface = buffer;
+}
+
+void CoordinatedBackingStore::createTile(int id, float scale)
+{
+ m_tiles.add(id, CoordinatedBackingStoreTile(scale));
+ m_scale = scale;
+}
+
+void CoordinatedBackingStore::removeTile(int id)
+{
+ m_tilesToRemove.append(id);
+}
+
+
+void CoordinatedBackingStore::updateTile(int id, const IntRect& sourceRect, const IntRect& targetRect, PassRefPtr<ShareableSurface> backBuffer, const IntPoint& offset)
+{
+ HashMap<int, CoordinatedBackingStoreTile>::iterator it = m_tiles.find(id);
+ ASSERT(it != m_tiles.end());
+ it->second.incrementRepaintCount();
+ it->second.setBackBuffer(targetRect, sourceRect, backBuffer, offset);
+}
+
+PassRefPtr<BitmapTexture> CoordinatedBackingStore::texture() const
+{
+ HashMap<int, CoordinatedBackingStoreTile>::const_iterator end = m_tiles.end();
+ for (HashMap<int, CoordinatedBackingStoreTile>::const_iterator it = m_tiles.begin(); it != end; ++it) {
+ RefPtr<BitmapTexture> texture = it->second.texture();
+ if (texture)
+ return texture;
+ }
+
+ return PassRefPtr<BitmapTexture>();
+}
+
+static bool shouldShowTileDebugVisuals()
+{
+#if PLATFORM(QT)
+ return (qgetenv("QT_WEBKIT_SHOW_COMPOSITING_DEBUG_VISUALS") == "1");
+#endif
+ return false;
+}
+
+void CoordinatedBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+{
+ Vector<TextureMapperTile*> tilesToPaint;
+
+ // We have to do this every time we paint, in case the opacity has changed.
+ HashMap<int, CoordinatedBackingStoreTile>::iterator end = m_tiles.end();
+ FloatRect coveredRect;
+ for (HashMap<int, CoordinatedBackingStoreTile>::iterator it = m_tiles.begin(); it != end; ++it) {
+ CoordinatedBackingStoreTile& tile = it->second;
+ if (!tile.texture())
+ continue;
+
+ if (tile.scale() == m_scale) {
+ tilesToPaint.append(&tile);
+ coveredRect.unite(tile.rect());
+ continue;
+ }
+
+ // Only show the previous tile if the opacity is high, otherwise effect looks like a bug.
+ // We show the previous-scale tile anyway if it doesn't intersect with any current-scale tile.
+ if (opacity < 0.95 && coveredRect.intersects(tile.rect()))
+ continue;
+
+ tilesToPaint.prepend(&tile);
+ }
+
+ // TODO: When the TextureMapper makes a distinction between some edges exposed and no edges
+ // exposed, the value passed should be an accurate reflection of the tile subset that we are
+ // passing. For now we just "estimate" since CoordinatedBackingStore doesn't keep information about
+ // the total tiled surface rect at the moment.
+ unsigned edgesExposed = m_tiles.size() > 1 ? TextureMapper::NoEdges : TextureMapper::AllEdges;
+ for (size_t i = 0; i < tilesToPaint.size(); ++i) {
+ TextureMapperTile* tile = tilesToPaint[i];
+ tile->paint(textureMapper, transform, opacity, mask, edgesExposed);
+ static bool shouldDebug = shouldShowTileDebugVisuals();
+ if (!shouldDebug)
+ continue;
+
+ textureMapper->drawBorder(Color(0xFF, 0, 0), 2, tile->rect(), transform);
+ textureMapper->drawRepaintCounter(static_cast<CoordinatedBackingStoreTile*>(tile)->repaintCount(), 8, tilesToPaint[i]->rect().location(), transform);
+ }
+}
+
+void CoordinatedBackingStore::commitTileOperations(TextureMapper* textureMapper)
+{
+ Vector<int>::iterator tilesToRemoveEnd = m_tilesToRemove.end();
+ for (Vector<int>::iterator it = m_tilesToRemove.begin(); it != tilesToRemoveEnd; ++it)
+ m_tiles.remove(*it);
+ m_tilesToRemove.clear();
+
+ HashMap<int, CoordinatedBackingStoreTile>::iterator tilesEnd = m_tiles.end();
+ for (HashMap<int, CoordinatedBackingStoreTile>::iterator it = m_tiles.begin(); it != tilesEnd; ++it)
+ it->second.swapBuffers(textureMapper);
+}
+
+} // namespace WebKit
+#endif
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.h b/Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.h
new file mode 100644
index 000000000..637feba70
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CoordinatedBackingStore_h
+#define CoordinatedBackingStore_h
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include "TextureMapper.h"
+#include "TextureMapperBackingStore.h"
+#include <wtf/HashMap.h>
+
+namespace WebKit {
+
+class ShareableSurface;
+
+class CoordinatedBackingStoreTile : public WebCore::TextureMapperTile {
+public:
+ CoordinatedBackingStoreTile(float scale = 1)
+ : TextureMapperTile(WebCore::FloatRect())
+ , m_scale(scale)
+ , m_repaintCount(0)
+ {
+ }
+
+ inline float scale() const { return m_scale; }
+ inline void incrementRepaintCount() { ++m_repaintCount; }
+ inline int repaintCount() const { return m_repaintCount; }
+ void swapBuffers(WebCore::TextureMapper*);
+ void setBackBuffer(const WebCore::IntRect&, const WebCore::IntRect&, PassRefPtr<ShareableSurface> buffer, const WebCore::IntPoint&);
+
+private:
+ RefPtr<ShareableSurface> m_surface;
+ WebCore::IntRect m_sourceRect;
+ WebCore::IntRect m_targetRect;
+ WebCore::IntPoint m_surfaceOffset;
+ float m_scale;
+ int m_repaintCount;
+};
+
+class CoordinatedBackingStore : public WebCore::TextureMapperBackingStore {
+public:
+ void createTile(int, float);
+ void removeTile(int);
+ void updateTile(int, const WebCore::IntRect&, const WebCore::IntRect&, PassRefPtr<ShareableSurface>, const WebCore::IntPoint&);
+ static PassRefPtr<CoordinatedBackingStore> create() { return adoptRef(new CoordinatedBackingStore); }
+ void commitTileOperations(WebCore::TextureMapper*);
+ PassRefPtr<WebCore::BitmapTexture> texture() const;
+ virtual void paintToTextureMapper(WebCore::TextureMapper*, const WebCore::FloatRect&, const WebCore::TransformationMatrix&, float, WebCore::BitmapTexture*);
+
+private:
+ CoordinatedBackingStore()
+ : m_scale(1.)
+ { }
+ HashMap<int, CoordinatedBackingStoreTile> m_tiles;
+ Vector<int> m_tilesToRemove;
+ float m_scale;
+};
+
+} // namespace WebKit
+#endif
+
+#endif // CoordinatedBackingStore_h
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp
new file mode 100644
index 000000000..ef972f3e3
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp
@@ -0,0 +1,188 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if USE(COORDINATED_GRAPHICS)
+#include "LayerTreeCoordinatorProxy.h"
+
+#include "LayerTreeCoordinatorMessages.h"
+#include "LayerTreeRenderer.h"
+#include "UpdateInfo.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebLayerTreeInfo.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+
+namespace WebKit {
+
+using namespace WebCore;
+
+LayerTreeCoordinatorProxy::LayerTreeCoordinatorProxy(DrawingAreaProxy* drawingAreaProxy)
+ : m_drawingAreaProxy(drawingAreaProxy)
+ , m_renderer(adoptRef(new LayerTreeRenderer(this)))
+ , m_lastSentScale(0)
+{
+}
+
+LayerTreeCoordinatorProxy::~LayerTreeCoordinatorProxy()
+{
+ m_renderer->detach();
+}
+
+void LayerTreeCoordinatorProxy::updateViewport()
+{
+ m_drawingAreaProxy->updateViewport();
+}
+
+void LayerTreeCoordinatorProxy::dispatchUpdate(const Function<void()>& function)
+{
+ m_renderer->appendUpdate(function);
+}
+
+void LayerTreeCoordinatorProxy::createTileForLayer(int layerID, int tileID, const IntRect& targetRect, const WebKit::SurfaceUpdateInfo& updateInfo)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::createTile, m_renderer.get(), layerID, tileID, updateInfo.scaleFactor));
+ updateTileForLayer(layerID, tileID, targetRect, updateInfo);
+}
+
+void LayerTreeCoordinatorProxy::updateTileForLayer(int layerID, int tileID, const IntRect& targetRect, const WebKit::SurfaceUpdateInfo& updateInfo)
+{
+ RefPtr<ShareableSurface> surface;
+#if USE(GRAPHICS_SURFACE)
+ int token = updateInfo.surfaceHandle.graphicsSurfaceToken();
+ if (token) {
+ HashMap<uint32_t, RefPtr<ShareableSurface> >::iterator it = m_surfaces.find(token);
+ if (it == m_surfaces.end()) {
+ surface = ShareableSurface::create(updateInfo.surfaceHandle);
+ m_surfaces.add(token, surface);
+ } else
+ surface = it->second;
+ } else
+ surface = ShareableSurface::create(updateInfo.surfaceHandle);
+#else
+ surface = ShareableSurface::create(updateInfo.surfaceHandle);
+#endif
+ dispatchUpdate(bind(&LayerTreeRenderer::updateTile, m_renderer.get(), layerID, tileID, LayerTreeRenderer::TileUpdate(updateInfo.updateRect, targetRect, surface, updateInfo.surfaceOffset)));
+}
+
+void LayerTreeCoordinatorProxy::removeTileForLayer(int layerID, int tileID)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::removeTile, m_renderer.get(), layerID, tileID));
+}
+
+void LayerTreeCoordinatorProxy::deleteCompositingLayer(WebLayerID id)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::deleteLayer, m_renderer.get(), id));
+ updateViewport();
+}
+
+void LayerTreeCoordinatorProxy::setRootCompositingLayer(WebLayerID id)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setRootLayerID, m_renderer.get(), id));
+ updateViewport();
+}
+
+void LayerTreeCoordinatorProxy::setCompositingLayerState(WebLayerID id, const WebLayerInfo& info)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setLayerState, m_renderer.get(), id, info));
+}
+
+void LayerTreeCoordinatorProxy::setCompositingLayerChildren(WebLayerID id, const Vector<WebLayerID>& children)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setLayerChildren, m_renderer.get(), id, children));
+}
+
+#if ENABLE(CSS_FILTERS)
+void LayerTreeCoordinatorProxy::setCompositingLayerFilters(WebLayerID id, const FilterOperations& filters)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setLayerFilters, m_renderer.get(), id, filters));
+}
+#endif
+
+void LayerTreeCoordinatorProxy::didRenderFrame()
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::flushLayerChanges, m_renderer.get()));
+ updateViewport();
+}
+
+void LayerTreeCoordinatorProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle)
+{
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
+ dispatchUpdate(bind(&LayerTreeRenderer::createImage, m_renderer.get(), key, bitmap));
+}
+
+void LayerTreeCoordinatorProxy::destroyDirectlyCompositedImage(int64_t key)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::destroyImage, m_renderer.get(), key));
+}
+
+void LayerTreeCoordinatorProxy::setContentsSize(const FloatSize& contentsSize)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setContentsSize, m_renderer.get(), contentsSize));
+}
+
+void LayerTreeCoordinatorProxy::setLayerAnimatedOpacity(uint32_t id, float opacity)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setAnimatedOpacity, m_renderer.get(), id, opacity));
+}
+
+void LayerTreeCoordinatorProxy::setLayerAnimatedTransform(uint32_t id, const WebCore::TransformationMatrix& transform)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::setAnimatedTransform, m_renderer.get(), id, transform));
+}
+
+void LayerTreeCoordinatorProxy::setVisibleContentsRect(const FloatRect& rect, float scale, const FloatPoint& trajectoryVector)
+{
+ // Inform the renderer to adjust viewport-fixed layers.
+ dispatchUpdate(bind(&LayerTreeRenderer::setVisibleContentsRect, m_renderer.get(), rect));
+
+ // Round the rect instead of enclosing it to make sure that its size stays the same while panning. This can have nasty effects on layout.
+ IntRect roundedRect = roundedIntRect(rect);
+ if (roundedRect == m_lastSentVisibleRect && scale == m_lastSentScale && trajectoryVector == m_lastSentTrajectoryVector)
+ return;
+
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::SetVisibleContentsRect(roundedRect, scale, trajectoryVector), m_drawingAreaProxy->page()->pageID());
+ m_lastSentVisibleRect = roundedRect;
+ m_lastSentScale = scale;
+ m_lastSentTrajectoryVector = trajectoryVector;
+}
+
+void LayerTreeCoordinatorProxy::renderNextFrame()
+{
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::RenderNextFrame(), m_drawingAreaProxy->page()->pageID());
+}
+
+void LayerTreeCoordinatorProxy::didChangeScrollPosition(const IntPoint& position)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::didChangeScrollPosition, m_renderer.get(), position));
+}
+
+void LayerTreeCoordinatorProxy::syncCanvas(uint32_t id, const IntSize& canvasSize, uint32_t graphicsSurfaceToken)
+{
+ dispatchUpdate(bind(&LayerTreeRenderer::syncCanvas, m_renderer.get(), id, canvasSize, graphicsSurfaceToken));
+}
+
+void LayerTreeCoordinatorProxy::purgeBackingStores()
+{
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID());
+}
+
+}
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h
new file mode 100644
index 000000000..f603cd0fc
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h
@@ -0,0 +1,99 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef LayerTreeCoordinatorProxy_h
+#define LayerTreeCoordinatorProxy_h
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include "BackingStore.h"
+#include "DrawingAreaProxy.h"
+#include "Region.h"
+#include "SurfaceUpdateInfo.h"
+#include "WebLayerTreeInfo.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/GraphicsLayer.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/IntSize.h>
+#include <WebCore/RunLoop.h>
+#include <WebCore/Timer.h>
+#include <wtf/Functional.h>
+#include <wtf/HashSet.h>
+
+#if PLATFORM(QT)
+QT_BEGIN_NAMESPACE
+class QSGNode;
+QT_END_NAMESPACE
+#endif
+
+namespace WebKit {
+
+class WebLayerInfo;
+class LayerTreeRenderer;
+class WebLayerUpdateInfo;
+
+class LayerTreeCoordinatorProxy {
+public:
+ LayerTreeCoordinatorProxy(DrawingAreaProxy*);
+ virtual ~LayerTreeCoordinatorProxy();
+ void setCompositingLayerState(WebLayerID, const WebLayerInfo&);
+ void setCompositingLayerChildren(WebLayerID, const Vector<WebLayerID>&);
+#if ENABLE(CSS_FILTERS)
+ void setCompositingLayerFilters(WebLayerID, const WebCore::FilterOperations&);
+#endif
+ void deleteCompositingLayer(WebLayerID);
+ void setRootCompositingLayer(WebLayerID);
+ void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+ void purgeGLResources();
+ void setContentsSize(const WebCore::FloatSize&);
+ void setVisibleContentsRect(const WebCore::FloatRect&, float scale, const WebCore::FloatPoint& trajectoryVector);
+ void didRenderFrame();
+ void createTileForLayer(int layerID, int tileID, const WebCore::IntRect&, const SurfaceUpdateInfo&);
+ void updateTileForLayer(int layerID, int tileID, const WebCore::IntRect&, const SurfaceUpdateInfo&);
+ void removeTileForLayer(int layerID, int tileID);
+ void createDirectlyCompositedImage(int64_t, const WebKit::ShareableBitmap::Handle&);
+ void destroyDirectlyCompositedImage(int64_t);
+ void didReceiveLayerTreeCoordinatorProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+ void updateViewport();
+ void renderNextFrame();
+ void didChangeScrollPosition(const WebCore::IntPoint& position);
+ void syncCanvas(uint32_t id, const WebCore::IntSize& canvasSize, uint32_t graphicsSurfaceToken);
+ void purgeBackingStores();
+ LayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); }
+ void setLayerAnimatedOpacity(uint32_t, float);
+ void setLayerAnimatedTransform(uint32_t, const WebCore::TransformationMatrix&);
+
+protected:
+ void dispatchUpdate(const Function<void()>&);
+
+ DrawingAreaProxy* m_drawingAreaProxy;
+ RefPtr<LayerTreeRenderer> m_renderer;
+ WebCore::IntRect m_lastSentVisibleRect;
+ float m_lastSentScale;
+ WebCore::FloatPoint m_lastSentTrajectoryVector;
+#if USE(GRAPHICS_SURFACE)
+ HashMap<uint32_t, RefPtr<ShareableSurface> > m_surfaces;
+#endif
+};
+
+}
+
+#endif
+
+#endif // LayerTreeCoordinatorProxy_h
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in
new file mode 100644
index 000000000..d2438f1f1
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+
+#if USE(COORDINATED_GRAPHICS)
+messages -> LayerTreeCoordinatorProxy {
+ SetCompositingLayerState(uint32_t id, WebKit::WebLayerInfo layerInfo)
+ SetCompositingLayerChildren(uint32_t id, Vector<uint32_t> children)
+#if ENABLE(CSS_FILTERS)
+ SetCompositingLayerFilters(uint32_t id, WebCore::FilterOperations filters)
+#endif
+ SetRootCompositingLayer(uint32_t id)
+ DeleteCompositingLayer(uint32_t id)
+ CreateTileForLayer(uint32_t layerID, int tileID, WebCore::IntRect targetRect, WebKit::SurfaceUpdateInfo updateInfo)
+ UpdateTileForLayer(uint32_t layerID, int tileID, WebCore::IntRect targetRect, WebKit::SurfaceUpdateInfo updateInfo)
+ RemoveTileForLayer(uint32_t layerID, int tileID)
+ CreateDirectlyCompositedImage(int64_t key, WebKit::ShareableBitmap::Handle handle)
+ DestroyDirectlyCompositedImage(int64_t key)
+ DidRenderFrame()
+ DidChangeScrollPosition(WebCore::IntPoint position)
+ SyncCanvas(uint32_t id, WebCore::IntSize canvasSize, uint32_t graphicsSurfaceToken)
+ SetLayerAnimatedOpacity(uint32_t id, float opacity)
+ SetLayerAnimatedTransform(uint32_t id, WebCore::TransformationMatrix transform)
+}
+#endif
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp
new file mode 100644
index 000000000..ed0be3c29
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp
@@ -0,0 +1,515 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include "LayerTreeRenderer.h"
+
+#include "CoordinatedBackingStore.h"
+#include "GraphicsLayerTextureMapper.h"
+#include "LayerTreeCoordinatorProxy.h"
+#include "MessageID.h"
+#include "ShareableBitmap.h"
+#include "TextureMapper.h"
+#include "TextureMapperBackingStore.h"
+#include "TextureMapperGL.h"
+#include "TextureMapperLayer.h"
+#include "UpdateInfo.h"
+#include <OpenGLShims.h>
+#include <wtf/Atomics.h>
+#include <wtf/MainThread.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+template<class T> class MainThreadGuardedInvoker {
+public:
+ static void call(PassRefPtr<T> objectToGuard, const Function<void()>& function)
+ {
+ MainThreadGuardedInvoker<T>* invoker = new MainThreadGuardedInvoker<T>(objectToGuard, function);
+ callOnMainThread(invoke, invoker);
+ }
+
+private:
+ MainThreadGuardedInvoker(PassRefPtr<T> object, const Function<void()>& newFunction)
+ : objectToGuard(object)
+ , function(newFunction)
+ {
+ }
+
+ RefPtr<T> objectToGuard;
+ Function<void()> function;
+ static void invoke(void* data)
+ {
+ MainThreadGuardedInvoker<T>* invoker = static_cast<MainThreadGuardedInvoker<T>*>(data);
+ invoker->function();
+ delete invoker;
+ }
+};
+
+void LayerTreeRenderer::callOnMainTread(const Function<void()>& function)
+{
+ if (isMainThread())
+ function();
+ else
+ MainThreadGuardedInvoker<LayerTreeRenderer>::call(this, function);
+}
+
+static FloatPoint boundedScrollPosition(const FloatPoint& scrollPosition, const FloatRect& visibleContentRect, const FloatSize& contentSize)
+{
+ float scrollPositionX = std::max(scrollPosition.x(), 0.0f);
+ scrollPositionX = std::min(scrollPositionX, contentSize.width() - visibleContentRect.width());
+
+ float scrollPositionY = std::max(scrollPosition.y(), 0.0f);
+ scrollPositionY = std::min(scrollPositionY, contentSize.height() - visibleContentRect.height());
+ return FloatPoint(scrollPositionX, scrollPositionY);
+}
+
+LayerTreeRenderer::LayerTreeRenderer(LayerTreeCoordinatorProxy* layerTreeCoordinatorProxy)
+ : m_layerTreeCoordinatorProxy(layerTreeCoordinatorProxy)
+ , m_rootLayerID(InvalidWebLayerID)
+ , m_isActive(false)
+{
+}
+
+LayerTreeRenderer::~LayerTreeRenderer()
+{
+}
+
+PassOwnPtr<GraphicsLayer> LayerTreeRenderer::createLayer(WebLayerID layerID)
+{
+ GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this);
+ TextureMapperLayer* layer = toTextureMapperLayer(newLayer);
+ layer->setShouldUpdateBackingStoreFromLayer(false);
+ return adoptPtr(newLayer);
+}
+
+void LayerTreeRenderer::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags)
+{
+ if (!m_textureMapper)
+ m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
+ ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
+
+ adjustPositionForFixedLayers();
+ GraphicsLayer* currentRootLayer = rootLayer();
+ if (!currentRootLayer)
+ return;
+
+ TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
+
+ if (!layer)
+ return;
+
+ layer->setTextureMapper(m_textureMapper.get());
+ m_textureMapper->beginPainting(PaintFlags);
+ m_textureMapper->beginClip(TransformationMatrix(), clipRect);
+
+ if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
+ currentRootLayer->setOpacity(opacity);
+ currentRootLayer->setTransform(matrix);
+ currentRootLayer->syncCompositingStateForThisLayerOnly();
+ }
+
+ layer->paint();
+ m_textureMapper->endClip();
+ m_textureMapper->endPainting();
+}
+
+void LayerTreeRenderer::paintToGraphicsContext(BackingStore::PlatformGraphicsContext painter)
+{
+ if (!m_textureMapper)
+ m_textureMapper = TextureMapper::create();
+ ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
+ syncRemoteContent();
+ TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
+
+ if (!layer)
+ return;
+
+ GraphicsContext graphicsContext(painter);
+ m_textureMapper->setGraphicsContext(&graphicsContext);
+ m_textureMapper->beginPainting();
+ layer->paint();
+ m_textureMapper->endPainting();
+ m_textureMapper->setGraphicsContext(0);
+}
+
+void LayerTreeRenderer::setContentsSize(const WebCore::FloatSize& contentsSize)
+{
+ m_contentsSize = contentsSize;
+}
+
+void LayerTreeRenderer::setVisibleContentsRect(const FloatRect& rect)
+{
+ m_visibleContentsRect = rect;
+}
+
+void LayerTreeRenderer::updateViewport()
+{
+ if (m_layerTreeCoordinatorProxy)
+ m_layerTreeCoordinatorProxy->updateViewport();
+}
+
+void LayerTreeRenderer::adjustPositionForFixedLayers()
+{
+ if (m_fixedLayers.isEmpty())
+ return;
+
+ // Fixed layer positions are updated by the web process when we update the visible contents rect / scroll position.
+ // If we want those layers to follow accurately the viewport when we move between the web process updates, we have to offset
+ // them by the delta between the current position and the position of the viewport used for the last layout.
+ FloatPoint scrollPosition = boundedScrollPosition(m_visibleContentsRect.location(), m_visibleContentsRect, m_contentsSize);
+ FloatPoint renderedScrollPosition = boundedScrollPosition(m_renderedContentsScrollPosition, m_visibleContentsRect, m_contentsSize);
+ FloatSize delta = scrollPosition - renderedScrollPosition;
+
+ LayerMap::iterator end = m_fixedLayers.end();
+ for (LayerMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
+ toTextureMapperLayer(it->second)->setScrollPositionDeltaIfNeeded(delta);
+}
+
+void LayerTreeRenderer::didChangeScrollPosition(const IntPoint& position)
+{
+ m_pendingRenderedContentsScrollPosition = position;
+}
+
+void LayerTreeRenderer::syncCanvas(WebLayerID id, const WebCore::IntSize& canvasSize, uint32_t graphicsSurfaceToken)
+{
+ if (canvasSize.isEmpty() || !m_textureMapper)
+ return;
+
+#if USE(GRAPHICS_SURFACE)
+ ensureLayer(id);
+ GraphicsLayer* layer = layerByID(id);
+
+ RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore;
+ SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(id);
+ if (it == m_surfaceBackingStores.end()) {
+ canvasBackingStore = TextureMapperSurfaceBackingStore::create();
+ m_surfaceBackingStores.set(id, canvasBackingStore);
+ } else
+ canvasBackingStore = it->second;
+
+ canvasBackingStore->setGraphicsSurface(graphicsSurfaceToken, canvasSize);
+ layer->setContentsToMedia(canvasBackingStore.get());
+#endif
+}
+
+void LayerTreeRenderer::setLayerChildren(WebLayerID id, const Vector<WebLayerID>& childIDs)
+{
+ ensureLayer(id);
+ LayerMap::iterator it = m_layers.find(id);
+ GraphicsLayer* layer = it->second;
+ Vector<GraphicsLayer*> children;
+
+ for (size_t i = 0; i < childIDs.size(); ++i) {
+ WebLayerID childID = childIDs[i];
+ GraphicsLayer* child = layerByID(childID);
+ if (!child) {
+ child = createLayer(childID).leakPtr();
+ m_layers.add(childID, child);
+ }
+ children.append(child);
+ }
+ layer->setChildren(children);
+}
+
+#if ENABLE(CSS_FILTERS)
+void LayerTreeRenderer::setLayerFilters(WebLayerID id, const FilterOperations& filters)
+{
+ ensureLayer(id);
+ LayerMap::iterator it = m_layers.find(id);
+ ASSERT(it != m_layers.end());
+
+ GraphicsLayer* layer = it->second;
+ layer->setFilters(filters);
+}
+#endif
+
+void LayerTreeRenderer::setLayerState(WebLayerID id, const WebLayerInfo& layerInfo)
+{
+ ensureLayer(id);
+ LayerMap::iterator it = m_layers.find(id);
+ ASSERT(it != m_layers.end());
+
+ GraphicsLayer* layer = it->second;
+
+ layer->setReplicatedByLayer(layerByID(layerInfo.replica));
+ layer->setMaskLayer(layerByID(layerInfo.mask));
+
+ layer->setPosition(layerInfo.pos);
+ layer->setSize(layerInfo.size);
+ layer->setTransform(layerInfo.transform);
+ layer->setAnchorPoint(layerInfo.anchorPoint);
+ layer->setChildrenTransform(layerInfo.childrenTransform);
+ layer->setBackfaceVisibility(layerInfo.backfaceVisible);
+ layer->setContentsOpaque(layerInfo.contentsOpaque);
+ layer->setContentsRect(layerInfo.contentsRect);
+ layer->setDrawsContent(layerInfo.drawsContent);
+ layer->setContentsVisible(layerInfo.contentsVisible);
+ toGraphicsLayerTextureMapper(layer)->setFixedToViewport(layerInfo.fixedToViewport);
+
+ if (layerInfo.fixedToViewport)
+ m_fixedLayers.add(id, layer);
+ else
+ m_fixedLayers.remove(id);
+
+ assignImageToLayer(layer, layerInfo.imageBackingStoreID);
+
+ // Never make the root layer clip.
+ layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds);
+ layer->setOpacity(layerInfo.opacity);
+ layer->setPreserves3D(layerInfo.preserves3D);
+ if (layerInfo.isRootLayer && m_rootLayerID != id)
+ setRootLayerID(id);
+}
+
+void LayerTreeRenderer::deleteLayer(WebLayerID layerID)
+{
+ GraphicsLayer* layer = layerByID(layerID);
+ if (!layer)
+ return;
+
+ layer->removeFromParent();
+ m_layers.remove(layerID);
+ m_fixedLayers.remove(layerID);
+#if USE(GRAPHICS_SURFACE)
+ m_surfaceBackingStores.remove(layerID);
+#endif
+ delete layer;
+}
+
+
+void LayerTreeRenderer::ensureLayer(WebLayerID id)
+{
+ // We have to leak the new layer's pointer and manage it ourselves,
+ // because OwnPtr is not copyable.
+ if (m_layers.find(id) == m_layers.end())
+ m_layers.add(id, createLayer(id).leakPtr());
+}
+
+void LayerTreeRenderer::setRootLayerID(WebLayerID layerID)
+{
+ if (layerID == m_rootLayerID)
+ return;
+
+ m_rootLayerID = layerID;
+
+ m_rootLayer->removeAllChildren();
+
+ if (!layerID)
+ return;
+
+ GraphicsLayer* layer = layerByID(layerID);
+ if (!layer)
+ return;
+
+ m_rootLayer->addChild(layer);
+}
+
+PassRefPtr<CoordinatedBackingStore> LayerTreeRenderer::getBackingStore(WebLayerID id)
+{
+ TextureMapperLayer* layer = toTextureMapperLayer(layerByID(id));
+ ASSERT(layer);
+ RefPtr<CoordinatedBackingStore> backingStore = static_cast<CoordinatedBackingStore*>(layer->backingStore().get());
+ if (!backingStore) {
+ backingStore = CoordinatedBackingStore::create();
+ layer->setBackingStore(backingStore.get());
+ }
+ ASSERT(backingStore);
+ return backingStore;
+}
+
+void LayerTreeRenderer::createTile(WebLayerID layerID, int tileID, float scale)
+{
+ getBackingStore(layerID)->createTile(tileID, scale);
+}
+
+void LayerTreeRenderer::removeTile(WebLayerID layerID, int tileID)
+{
+ getBackingStore(layerID)->removeTile(tileID);
+}
+
+void LayerTreeRenderer::updateTile(WebLayerID layerID, int tileID, const TileUpdate& update)
+{
+ RefPtr<CoordinatedBackingStore> backingStore = getBackingStore(layerID);
+ backingStore->updateTile(tileID, update.sourceRect, update.targetRect, update.surface, update.offset);
+ m_backingStoresWithPendingBuffers.add(backingStore);
+}
+
+void LayerTreeRenderer::createImage(int64_t imageID, PassRefPtr<ShareableBitmap> weakBitmap)
+{
+ RefPtr<ShareableBitmap> bitmap = weakBitmap;
+ RefPtr<TextureMapperTiledBackingStore> backingStore = TextureMapperTiledBackingStore::create();
+ m_directlyCompositedImages.set(imageID, backingStore);
+ backingStore->updateContents(m_textureMapper.get(), bitmap->createImage().get());
+}
+
+void LayerTreeRenderer::destroyImage(int64_t imageID)
+{
+ m_directlyCompositedImages.remove(imageID);
+}
+
+void LayerTreeRenderer::assignImageToLayer(GraphicsLayer* layer, int64_t imageID)
+{
+ if (!imageID) {
+ layer->setContentsToMedia(0);
+ return;
+ }
+
+ HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID);
+ ASSERT(it != m_directlyCompositedImages.end());
+ layer->setContentsToMedia(it->second.get());
+}
+
+void LayerTreeRenderer::commitTileOperations()
+{
+ HashSet<RefPtr<CoordinatedBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
+ for (HashSet<RefPtr<CoordinatedBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it)
+ (*it)->commitTileOperations(m_textureMapper.get());
+
+ m_backingStoresWithPendingBuffers.clear();
+}
+
+void LayerTreeRenderer::flushLayerChanges()
+{
+ m_renderedContentsScrollPosition = m_pendingRenderedContentsScrollPosition;
+
+ m_rootLayer->syncCompositingState(FloatRect());
+ commitTileOperations();
+
+ // The pending tiles state is on its way for the screen, tell the web process to render the next one.
+ callOnMainThread(bind(&LayerTreeRenderer::renderNextFrame, this));
+}
+
+void LayerTreeRenderer::renderNextFrame()
+{
+ if (m_layerTreeCoordinatorProxy)
+ m_layerTreeCoordinatorProxy->renderNextFrame();
+}
+
+void LayerTreeRenderer::ensureRootLayer()
+{
+ if (m_rootLayer)
+ return;
+ if (!m_textureMapper) {
+ m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
+ static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
+ }
+
+ m_rootLayer = createLayer(InvalidWebLayerID);
+ m_rootLayer->setMasksToBounds(false);
+ m_rootLayer->setDrawsContent(false);
+ m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
+
+ // The root layer should not have zero size, or it would be optimized out.
+ m_rootLayer->setSize(FloatSize(1.0, 1.0));
+ toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
+}
+
+void LayerTreeRenderer::syncRemoteContent()
+{
+ // We enqueue messages and execute them during paint, as they require an active GL context.
+ ensureRootLayer();
+
+ for (size_t i = 0; i < m_renderQueue.size(); ++i)
+ m_renderQueue[i]();
+
+ m_renderQueue.clear();
+}
+
+void LayerTreeRenderer::purgeGLResources()
+{
+ TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
+
+ if (layer)
+ layer->clearBackingStoresRecursive();
+
+ m_directlyCompositedImages.clear();
+#if USE(GRAPHICS_SURFACE)
+ m_surfaceBackingStores.clear();
+#endif
+
+ m_rootLayer->removeAllChildren();
+ m_rootLayer.clear();
+ m_rootLayerID = InvalidWebLayerID;
+ m_layers.clear();
+ m_fixedLayers.clear();
+ m_textureMapper.clear();
+ m_backingStoresWithPendingBuffers.clear();
+
+ setActive(false);
+
+ callOnMainThread(bind(&LayerTreeRenderer::purgeBackingStores, this));
+}
+
+void LayerTreeRenderer::setAnimatedOpacity(uint32_t id, float opacity)
+{
+ GraphicsLayer* layer = layerByID(id);
+ ASSERT(layer);
+
+ layer->setOpacity(opacity);
+}
+
+void LayerTreeRenderer::setAnimatedTransform(uint32_t id, const WebCore::TransformationMatrix& transform)
+{
+ GraphicsLayer* layer = layerByID(id);
+ ASSERT(layer);
+
+ layer->setTransform(transform);
+}
+
+void LayerTreeRenderer::purgeBackingStores()
+{
+ if (m_layerTreeCoordinatorProxy)
+ m_layerTreeCoordinatorProxy->purgeBackingStores();
+}
+
+void LayerTreeRenderer::detach()
+{
+ m_layerTreeCoordinatorProxy = 0;
+}
+
+void LayerTreeRenderer::appendUpdate(const Function<void()>& function)
+{
+ if (!m_isActive)
+ return;
+
+ m_renderQueue.append(function);
+}
+
+void LayerTreeRenderer::setActive(bool active)
+{
+ if (m_isActive == active)
+ return;
+
+ // Have to clear render queue in both cases.
+ // If there are some updates in queue during activation then those updates are from previous instance of paint node
+ // and cannot be applied to the newly created instance.
+ m_renderQueue.clear();
+ m_isActive = active;
+ if (m_isActive)
+ renderNextFrame();
+}
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.h b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.h
new file mode 100644
index 000000000..6403b5d2d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.h
@@ -0,0 +1,156 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef LayerTreeRenderer_h
+#define LayerTreeRenderer_h
+
+#if USE(COORDINATED_GRAPHICS)
+#include "BackingStore.h"
+#include "GraphicsSurface.h"
+#include "ShareableSurface.h"
+#include "TextureMapper.h"
+#include "TextureMapperBackingStore.h"
+#include "WebLayerTreeInfo.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/GraphicsLayer.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/IntSize.h>
+#include <WebCore/RunLoop.h>
+#include <WebCore/Timer.h>
+#include <wtf/Functional.h>
+#include <wtf/HashSet.h>
+#include <wtf/ThreadingPrimitives.h>
+
+namespace WebKit {
+
+class CoordinatedBackingStore;
+class LayerTreeCoordinatorProxy;
+class WebLayerInfo;
+class WebLayerUpdateInfo;
+
+class LayerTreeRenderer : public ThreadSafeRefCounted<LayerTreeRenderer>, public WebCore::GraphicsLayerClient {
+public:
+ struct TileUpdate {
+ WebCore::IntRect sourceRect;
+ WebCore::IntRect targetRect;
+ RefPtr<ShareableSurface> surface;
+ WebCore::IntPoint offset;
+ TileUpdate(const WebCore::IntRect& source, const WebCore::IntRect& target, PassRefPtr<ShareableSurface> newSurface, const WebCore::IntPoint& newOffset)
+ : sourceRect(source)
+ , targetRect(target)
+ , surface(newSurface)
+ , offset(newOffset)
+ {
+ }
+ };
+ LayerTreeRenderer(LayerTreeCoordinatorProxy*);
+ virtual ~LayerTreeRenderer();
+ void purgeGLResources();
+ void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&, WebCore::TextureMapper::PaintFlags = 0);
+ void paintToGraphicsContext(BackingStore::PlatformGraphicsContext);
+ void syncRemoteContent();
+ void setContentsSize(const WebCore::FloatSize&);
+ void setVisibleContentsRect(const WebCore::FloatRect&);
+ void didChangeScrollPosition(const WebCore::IntPoint& position);
+ void syncCanvas(uint32_t id, const WebCore::IntSize& canvasSize, uint32_t graphicsSurfaceToken);
+
+ void detach();
+ void appendUpdate(const Function<void()>&);
+ void updateViewport();
+ void setActive(bool);
+
+ void deleteLayer(WebLayerID);
+ void setRootLayerID(WebLayerID);
+ void setLayerChildren(WebLayerID, const Vector<WebLayerID>&);
+ void setLayerState(WebLayerID, const WebLayerInfo&);
+#if ENABLE(CSS_FILTERS)
+ void setLayerFilters(WebLayerID, const WebCore::FilterOperations&);
+#endif
+
+ void createTile(WebLayerID, int, float scale);
+ void removeTile(WebLayerID, int);
+ void updateTile(WebLayerID, int, const TileUpdate&);
+ void flushLayerChanges();
+ void createImage(int64_t, PassRefPtr<ShareableBitmap>);
+ void destroyImage(int64_t);
+ void setAnimatedOpacity(uint32_t, float);
+ void setAnimatedTransform(uint32_t, const WebCore::TransformationMatrix&);
+
+private:
+ PassOwnPtr<WebCore::GraphicsLayer> createLayer(WebLayerID);
+
+ WebCore::GraphicsLayer* layerByID(WebLayerID id) { return (id == InvalidWebLayerID) ? 0 : m_layers.get(id); }
+ WebCore::GraphicsLayer* rootLayer() { return m_rootLayer.get(); }
+
+ // Reimplementations from WebCore::GraphicsLayerClient.
+ virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double) { }
+ virtual void notifySyncRequired(const WebCore::GraphicsLayer*) { }
+ virtual bool showDebugBorders(const WebCore::GraphicsLayer*) const { return false; }
+ virtual bool showRepaintCounter(const WebCore::GraphicsLayer*) const { return false; }
+ void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect&) { }
+ void callOnMainTread(const Function<void()>&);
+ void adjustPositionForFixedLayers();
+
+ typedef HashMap<WebLayerID, WebCore::GraphicsLayer*> LayerMap;
+ WebCore::FloatSize m_contentsSize;
+ WebCore::FloatRect m_visibleContentsRect;
+
+ // Render queue can be accessed ony from main thread or updatePaintNode call stack!
+ Vector<Function<void()> > m_renderQueue;
+
+#if USE(TEXTURE_MAPPER)
+ OwnPtr<WebCore::TextureMapper> m_textureMapper;
+ PassRefPtr<CoordinatedBackingStore> getBackingStore(WebLayerID);
+ HashMap<int64_t, RefPtr<WebCore::TextureMapperBackingStore> > m_directlyCompositedImages;
+ HashSet<RefPtr<CoordinatedBackingStore> > m_backingStoresWithPendingBuffers;
+#endif
+#if USE(GRAPHICS_SURFACE)
+ typedef HashMap<WebLayerID, RefPtr<WebCore::TextureMapperSurfaceBackingStore> > SurfaceBackingStoreMap;
+ SurfaceBackingStoreMap m_surfaceBackingStores;
+#endif
+
+ void scheduleWebViewUpdate();
+ void synchronizeViewport();
+ void assignImageToLayer(WebCore::GraphicsLayer*, int64_t imageID);
+ void ensureRootLayer();
+ void ensureLayer(WebLayerID);
+ void commitTileOperations();
+ void syncAnimations();
+ void renderNextFrame();
+ void purgeBackingStores();
+
+ LayerTreeCoordinatorProxy* m_layerTreeCoordinatorProxy;
+ OwnPtr<WebCore::GraphicsLayer> m_rootLayer;
+ Vector<WebLayerID> m_layersToDelete;
+
+ LayerMap m_layers;
+ LayerMap m_fixedLayers;
+ WebLayerID m_rootLayerID;
+ WebCore::IntPoint m_renderedContentsScrollPosition;
+ WebCore::IntPoint m_pendingRenderedContentsScrollPosition;
+ bool m_isActive;
+};
+
+};
+
+#endif // USE(COORDINATED_GRAPHICS)
+
+#endif // LayerTreeRenderer_h
+
+