diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/CoordinatedGraphics')
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 + + |
