| /* |
| 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 WebCore::IntRect& tileRect, const WebCore::IntSize& backingSize, const WebKit::SurfaceUpdateInfo& updateInfo) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::createTile, m_renderer.get(), layerID, tileID, updateInfo.scaleFactor, backingSize)); |
| updateTileForLayer(layerID, tileID, tileRect, updateInfo); |
| } |
| |
| void LayerTreeCoordinatorProxy::updateTileForLayer(int layerID, int tileID, const IntRect& tileRect, const WebKit::SurfaceUpdateInfo& updateInfo) |
| { |
| SurfaceMap::iterator it = m_surfaces.find(updateInfo.atlasID); |
| ASSERT(it != m_surfaces.end()); |
| dispatchUpdate(bind(&LayerTreeRenderer::updateTile, m_renderer.get(), layerID, tileID, LayerTreeRenderer::TileUpdate(updateInfo.updateRect, tileRect, it->value, updateInfo.surfaceOffset))); |
| } |
| |
| void LayerTreeCoordinatorProxy::removeTileForLayer(int layerID, int tileID) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::removeTile, m_renderer.get(), layerID, tileID)); |
| } |
| |
| void LayerTreeCoordinatorProxy::createUpdateAtlas(int atlasID, const ShareableSurface::Handle& handle) |
| { |
| ASSERT(!m_surfaces.contains(atlasID)); |
| m_surfaces.add(atlasID, ShareableSurface::create(handle)); |
| } |
| |
| void LayerTreeCoordinatorProxy::removeUpdateAtlas(int atlasID) |
| { |
| ASSERT(m_surfaces.contains(atlasID)); |
| m_surfaces.remove(atlasID); |
| } |
| |
| 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(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::flushLayerChanges, m_renderer.get())); |
| updateViewport(); |
| #if USE(TILED_BACKING_STORE) |
| m_drawingAreaProxy->page()->didRenderFrame(contentsSize, coveredRect); |
| #else |
| UNUSED_PARAM(contentsSize); |
| UNUSED_PARAM(coveredRect); |
| #endif |
| } |
| |
| 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::setLayerAnimations(WebLayerID id, const GraphicsLayerAnimations& animations) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::setLayerAnimations, m_renderer.get(), id, animations)); |
| } |
| |
| void LayerTreeCoordinatorProxy::setAnimationsLocked(bool locked) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::setAnimationsLocked, m_renderer.get(), locked)); |
| } |
| |
| 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()); |
| } |
| |
| #if ENABLE(REQUEST_ANIMATION_FRAME) |
| void LayerTreeCoordinatorProxy::requestAnimationFrame() |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::requestAnimationFrame, m_renderer.get())); |
| updateViewport(); |
| } |
| |
| void LayerTreeCoordinatorProxy::animationFrameReady() |
| { |
| m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::AnimationFrameReady(), m_drawingAreaProxy->page()->pageID()); |
| } |
| #endif |
| |
| void LayerTreeCoordinatorProxy::didChangeScrollPosition(const IntPoint& position) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::didChangeScrollPosition, m_renderer.get(), position)); |
| } |
| |
| #if USE(GRAPHICS_SURFACE) |
| void LayerTreeCoordinatorProxy::syncCanvas(uint32_t id, const IntSize& canvasSize, const GraphicsSurfaceToken& token, uint32_t frontBuffer) |
| { |
| dispatchUpdate(bind(&LayerTreeRenderer::syncCanvas, m_renderer.get(), id, canvasSize, token, frontBuffer)); |
| } |
| #endif |
| |
| void LayerTreeCoordinatorProxy::purgeBackingStores() |
| { |
| m_surfaces.clear(); |
| m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeCoordinator::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID()); |
| } |
| |
| } |
| #endif // USE(COORDINATED_GRAPHICS) |