WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-109579-20130322171642.patch (text/plain), 44.09 KB, created by
Balazs Kelemen
on 2013-03-22 09:21:21 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Balazs Kelemen
Created:
2013-03-22 09:21:21 PDT
Size:
44.09 KB
patch
obsolete
>Subversion Revision: 146594 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 140352fe2c4615bcc7fc5b8d9e02f98a11fad430..cb9810b93ed422abd035fdfe95524a702b092a86 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,93 @@ >+2013-03-22 Balazs Kelemen <kbalazs@webkit.org> >+ >+ [CoordGfx] Speed up web process rendering with double buffering >+ https://bugs.webkit.org/show_bug.cgi?id=109579 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Covered by all tests related to rendering. >+ >+ Render the new frame ahead of time while the UI process is updating. >+ This is an optimization that has the most value for animations that are heavy in layout/repaint. >+ To make it possible we need a double buffering mechanism. This has been implemented >+ by introducing a marked state for nodes in AreaAllocator. The marked nodes represent >+ the back buffers that can be reused after the UI process sends RenderNextFrame. >+ The prerendered frame (the result of a flush that happened while the UI was processing >+ the last frame) should be invalidated and rerendered if the layout changes. In this case >+ the CoordinatedGraphicsState will be a result of multiple flushes. The patch adds logic >+ to handle that. >+ >+ * platform/graphics/texmap/coordinated/AreaAllocator.cpp: >+ (WebCore::GeneralAreaAllocator::GeneralAreaAllocator): >+ (WebCore::GeneralAreaAllocator::splitNode): >+ (WebCore::GeneralAreaAllocator::release): >+ (WebCore): >+ (WebCore::GeneralAreaAllocator::releaseNode): >+ (WebCore::GeneralAreaAllocator::markAllocations): >+ (WebCore::GeneralAreaAllocator::clearMarkedAllocations): >+ (WebCore::GeneralAreaAllocator::hasAllocations): >+ * platform/graphics/texmap/coordinated/AreaAllocator.h: >+ (AreaAllocator): >+ (GeneralAreaAllocator): >+ * platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp: >+ (WebCore::CoordinatedBackingStoreTile::swapBuffers): >+ (WebCore::CoordinatedBackingStoreTile::addUpdate): >+ (WebCore::CoordinatedBackingStore::updateTile): >+ * platform/graphics/texmap/coordinated/CoordinatedBackingStore.h: >+ (CoordinatedBackingStoreTile): >+ (WebCore::CoordinatedBackingStoreTile::Update::Update): >+ (Update): >+ Now we can have multiple tile updates for a given tile. Copy all of >+ them to the texture in order. >+ * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp: >+ (WebCore::CoordinatedGraphicsLayer::CoordinatedGraphicsLayer): >+ (WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly): >+ Keep the layer state. We might collect it for multiple flushes. Resetting is >+ controlled by the coordinator via didCommitLayerState. >+ (WebCore::CoordinatedGraphicsLayer::didCommitLayerState): >+ (WebCore::CoordinatedGraphicsLayer::createTile): Don't add a tile with the same id >+ twice, instead keep the latest. There is virtually no chance for that to actually >+ happen because of the way tile id's are generated but I added this for consistency. >+ (WebCore::CoordinatedGraphicsLayer::updateTile): Handle multiple updates for a tile. >+ (WebCore::CoordinatedGraphicsLayer::removeTile): Handle the case if the tile we are >+ removing has not been committed at all. >+ (WebCore::CoordinatedGraphicsLayer::purgeBackingStores): >+ * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h: >+ (CoordinatedGraphicsLayer): >+ * platform/graphics/texmap/coordinated/CoordinatedGraphicsScene.cpp: >+ (WebCore::CoordinatedGraphicsScene::createTilesIfNeeded): >+ (WebCore::CoordinatedGraphicsScene::removeTilesIfNeeded): >+ (WebCore::CoordinatedGraphicsScene::updateTilesIfNeeded): >+ (WebCore::CoordinatedGraphicsScene::commitSceneState): >+ Aligned to the changes in CoordinatedGraphicsState. >+ * platform/graphics/texmap/coordinated/CoordinatedGraphicsScene.h: >+ * platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h: >+ (WebCore): >+ (TileCreationInfo): >+ (WebCore::TileCreationInfo::TileCreationInfo): >+ (WebCore::TileCreationInfoHash::hash): >+ (WebCore::TileCreationInfoHash::equal): >+ (TileCreationInfoHash): >+ (TileCreationInfoHashTraits): >+ (WebCore::TileCreationInfoHashTraits::emptyValue): >+ (WebCore::TileCreationInfoHashTraits::isEmptyValue): >+ (WebCore::TileCreationInfoHashTraits::constructEmtpyValue): >+ (WebCore::TileCreationInfoHashTraits::deletedValue): >+ (WebCore::TileCreationInfoHashTraits::isDeletedValue): >+ (WebCore::TileCreationInfoHashTraits::constructDeletedValue): >+ (CoordinatedGraphicsLayerState): >+ (CoordinatedGraphicsState): >+ Use associative data structures for tile operations to make the merging of >+ multiple flushes fast. >+ * platform/graphics/texmap/coordinated/UpdateAtlas.cpp: >+ (WebCore::UpdateAtlas::UpdateAtlas): >+ (WebCore::UpdateAtlas::didCommitBuffers): >+ (WebCore::UpdateAtlas::didSwapBuffers): >+ (WebCore::UpdateAtlas::beginPaintingOnAvailableBuffer): >+ * platform/graphics/texmap/coordinated/UpdateAtlas.h: >+ (UpdateAtlas): >+ (WebCore::UpdateAtlas::isInUse): >+ > 2013-03-22 Yury Semikhatsky <yurys@chromium.org> > > Unreviewed. Fix Chromium Win compilation after r146583. >diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog >index aacb22225c8ed04cfcef6961e1230d85354607dd..ff17e9e0604ca721a83ab2b09bab977149c1a628 100644 >--- a/Source/WebKit2/ChangeLog >+++ b/Source/WebKit2/ChangeLog >@@ -1,3 +1,43 @@ >+2013-03-22 Balazs Kelemen <kbalazs@webkit.org> >+ >+ [CoordGfx] Speed up web process rendering with double buffering >+ https://bugs.webkit.org/show_bug.cgi?id=109579 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Render the new frame ahead of time while the UI process is updating. >+ This is an optimization that has the most value for animations that are heavy in layout/repaint. >+ To make it possible we need a double buffering mechanism. This has been implemented >+ by introducing a marked state for nodes in AreaAllocator. The marked nodes represent >+ the back buffers that can be reused after the UI process sends RenderNextFrame. >+ The prerendered frame (the result of a flush that happened while the UI was processing >+ the last frame) should be invalidated and rerendered if the layout changes. In this case >+ the CoordinatedGraphicsState will be a result of multiple flushes. The patch adds logic >+ to handle that. >+ >+ * Platform/CoreIPC/ArgumentCoders.h: >+ Added coder for WTF::HashSet. >+ * Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp: >+ (CoreIPC::::encode): >+ (CoreIPC::::decode): >+ Align to the changes in CoordinatedGraphicsState. >+ * UIProcess/CoordinatedGraphics/CoordinatedLayerTreeHostProxy.cpp: >+ * UIProcess/CoordinatedGraphics/CoordinatedLayerTreeHostProxy.h: >+ * WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp: >+ (WebKit::CoordinatedLayerTreeHost::CoordinatedLayerTreeHost): >+ (WebKit::CoordinatedLayerTreeHost::scheduleLayerFlush): >+ (WebKit::CoordinatedLayerTreeHost::shouldFlushLayerChanges): >+ (WebKit): >+ (WebKit::CoordinatedLayerTreeHost::flushPendingLayerChanges): >+ (WebKit::CoordinatedLayerTreeHost::commitFrame): >+ (WebKit::CoordinatedLayerTreeHost::syncLayerState): >+ (WebKit::CoordinatedLayerTreeHost::performScheduledLayerFlush): >+ (WebKit::CoordinatedLayerTreeHost::syncDisplayState): >+ (WebKit::CoordinatedLayerTreeHost::updateImageBacking): >+ (WebKit::CoordinatedLayerTreeHost::renderNextFrame): >+ * WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h: >+ Extend the state machine to handle prerendering frames and double buffering. >+ > 2013-03-21 Tim Horton <timothy_horton@apple.com> > > [wk2] Page Overlays: Don't create backing store until the client asks us to paint >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.cpp >index 9f54185b98e8a708a6d6f1ab2045d2b123483601..58465458d8d93d259061f5fb784d7e8e8ff2adba 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.cpp >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.cpp >@@ -80,6 +80,9 @@ GeneralAreaAllocator::GeneralAreaAllocator(const IntSize& size) > m_root->right = 0; > m_nodeCount = 1; > setMinimumAllocation(IntSize(8, 8)); >+#if !ASSERT_DISABLED >+ m_markState = UnmarkedState; >+#endif > } > > GeneralAreaAllocator::~GeneralAreaAllocator() >@@ -239,8 +242,7 @@ IntPoint GeneralAreaAllocator::allocateFromNode(const IntSize& size, Node* node) > return IntPoint(-1, -1); > } > >-GeneralAreaAllocator::Node* GeneralAreaAllocator::splitNode >- (Node* node, Split split) >+GeneralAreaAllocator::Node* GeneralAreaAllocator::splitNode(Node* node, Split split) > { > Node* left = new Node(); > Node* right = new Node(); >@@ -300,6 +302,11 @@ void GeneralAreaAllocator::release(const IntRect& rect) > if (!node) > return; > >+ releaseNode(node); >+} >+ >+void GeneralAreaAllocator::releaseNode(Node* node) >+{ > // Mark the node as free and then work upwards through the tree > // recombining and deleting nodes until we reach a sibling > // that is still allocated. >@@ -330,6 +337,51 @@ int GeneralAreaAllocator::overhead() const > return m_nodeCount * sizeof(Node); > } > >+void GeneralAreaAllocator::markAllocations() >+{ >+#if !ASSERT_DISABLED >+ ASSERT(m_markState == UnmarkedState); >+ m_markState = MarkedState; >+#endif >+ // Mark allocated leaves. >+ NodeList stack; >+ stack.append(m_root); >+ while (!stack.isEmpty()) { >+ Node* current = stack.last(); >+ stack.removeLast(); >+ Node* left = current->left; >+ Node* right = current->right; >+ if (current->largestFree.isEmpty() && !left && !right) >+ m_markedNodes.append(current); >+ else { >+ if (left) >+ stack.append(left); >+ if (right) >+ stack.append(right); >+ } >+ } >+} >+ >+void GeneralAreaAllocator::clearMarkedAllocations() >+{ >+#if !ASSERT_DISABLED >+ ASSERT(m_markState == MarkedState); >+ m_markState = UnmarkedState; >+#endif >+ for (size_t i = 0; i < m_markedNodes.size(); ++i) { >+ Node* n = m_markedNodes[i]; >+ ASSERT(n->largestFree.isEmpty() && !n->left && !n->right); >+ releaseNode(n); >+ } >+ m_markedNodes.clear(); >+} >+ >+bool GeneralAreaAllocator::hasAllocations() const >+{ >+ ASSERT(m_root->largestFree == m_size || (m_root->left || m_root->right)); >+ return m_root->largestFree != m_size; >+} >+ > } // namespace WebCore > > #endif // USE(COORDINATED_GRAPHICS) >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.h b/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.h >index 4180cae237750f6fa343b0bc7f2a93093908d32f..3e57502e9a5c5cb9fc0c95492e68c66be1cae688 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.h >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/AreaAllocator.h >@@ -23,6 +23,7 @@ > #include "IntPoint.h" > #include "IntRect.h" > #include "IntSize.h" >+#include <wtf/Vector.h> > > #if USE(COORDINATED_GRAPHICS) > >@@ -67,6 +68,13 @@ public: > > virtual int overhead() const; > >+ // We use a marking mechanism to keep track of allocations that can be reused later. >+ // It makes possible to devide the area into back and front buffers. >+ virtual void markAllocations() = 0; >+ virtual void clearMarkedAllocations() = 0; >+ >+ virtual bool hasAllocations() const = 0; >+ > protected: > IntSize m_size; > IntSize m_minAlloc; >@@ -85,6 +93,11 @@ public: > void release(const IntRect&); > int overhead() const; > >+ virtual void markAllocations() OVERRIDE; >+ virtual void clearMarkedAllocations() OVERRIDE; >+ >+ virtual bool hasAllocations() const OVERRIDE; >+ > private: > enum Split { SplitOnX, SplitOnY }; > >@@ -96,11 +109,21 @@ private: > Node* right; > }; > >+ typedef Vector<Node*, 8> NodeList; >+ > Node* m_root; >+ NodeList m_markedNodes; > int m_nodeCount; >+#if !ASSERT_DISABLED >+ enum { >+ MarkedState, >+ UnmarkedState >+ } m_markState; >+#endif > > static void freeNode(Node*); > IntPoint allocateFromNode(const IntSize&, Node*); >+ void releaseNode(Node*); > Node* splitNode(Node*, Split); > static void updateLargestFree(Node*); > }; >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp >index cd5a12d967b650b9908de102c4c29133a52e0b94..ddc8f86182c40960e1a8525f94a4b52db2fa59ae 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp >@@ -30,7 +30,7 @@ namespace WebCore { > > void CoordinatedBackingStoreTile::swapBuffers(TextureMapper* textureMapper) > { >- if (!m_surface) >+ if (m_updates.isEmpty()) > return; > > FloatRect tileRect(m_tileRect); >@@ -49,18 +49,22 @@ void CoordinatedBackingStoreTile::swapBuffers(TextureMapper* textureMapper) > > ASSERT(textureMapper->maxTextureSize().width() >= m_tileRect.size().width() && textureMapper->maxTextureSize().height() >= m_tileRect.size().height()); > if (shouldReset) >- texture->reset(m_tileRect.size(), m_surface->supportsAlpha()); >+ texture->reset(m_tileRect.size(), m_updates.first().surface->supportsAlpha()); > >- m_surface->copyToTexture(texture, m_sourceRect, m_surfaceOffset); >- m_surface.clear(); >+ for (size_t i = 0; i < m_updates.size(); ++i) { >+ Update& update = m_updates[i]; >+ ASSERT(update.surface->supportsAlpha() == m_updates.first().surface->supportsAlpha()); >+ update.surface->copyToTexture(texture, update.sourceRect, update.surfaceOffset); >+ } >+ m_updates.clear(); > } > >-void CoordinatedBackingStoreTile::setBackBuffer(const IntRect& tileRect, const IntRect& sourceRect, PassRefPtr<CoordinatedSurface> buffer, const IntPoint& offset) >+void CoordinatedBackingStoreTile::addUpdate(const IntRect& tileRect, const IntRect& sourceRect, PassRefPtr<CoordinatedSurface> buffer, const IntPoint& offset) > { >- m_sourceRect = sourceRect; >+ // Make sure we don't mix incompatible updates. >+ ASSERT(m_tileRect == tileRect || m_updates.isEmpty()); > m_tileRect = tileRect; >- m_surfaceOffset = offset; >- m_surface = buffer; >+ m_updates.append(Update(buffer, sourceRect, offset)); > } > > void CoordinatedBackingStore::createTile(uint32_t id, float scale) >@@ -86,7 +90,7 @@ void CoordinatedBackingStore::updateTile(uint32_t id, const IntRect& sourceRect, > { > CoordinatedBackingStoreTileMap::iterator it = m_tiles.find(id); > ASSERT(it != m_tiles.end()); >- it->value.setBackBuffer(tileRect, sourceRect, backBuffer, offset); >+ it->value.addUpdate(tileRect, sourceRect, backBuffer, offset); > } > > PassRefPtr<BitmapTexture> CoordinatedBackingStore::texture() const >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.h b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.h >index 4201454bd7f75c363a268b72b387511de0e71a7b..9ba8310306969ff085ef3214ea632a246bb09bb3 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.h >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.h >@@ -27,6 +27,7 @@ > #include "TextureMapperTile.h" > #include <wtf/HashMap.h> > #include <wtf/HashSet.h> >+#include <wtf/Vector.h> > > namespace WebCore { > >@@ -42,13 +43,21 @@ public: > > inline float scale() const { return m_scale; } > void swapBuffers(TextureMapper*); >- void setBackBuffer(const IntRect&, const IntRect&, PassRefPtr<CoordinatedSurface> buffer, const IntPoint&); >+ void addUpdate(const IntRect&, const IntRect&, PassRefPtr<CoordinatedSurface> buffer, const IntPoint&); > > private: >- RefPtr<CoordinatedSurface> m_surface; >- IntRect m_sourceRect; >+ struct Update { >+ Update(PassRefPtr<CoordinatedSurface> surface, const IntRect& sourceRect, const IntPoint& offset) >+ : surface(surface) >+ , sourceRect(sourceRect) >+ , surfaceOffset(offset) >+ { } >+ RefPtr<CoordinatedSurface> surface; >+ IntRect sourceRect; >+ IntPoint surfaceOffset; >+ }; >+ Vector<Update> m_updates; > IntRect m_tileRect; >- IntPoint m_surfaceOffset; > float m_scale; > }; > >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp >index 36ae04769d3baac4698ab0a7f32a689441ab0558..ff8676e1ab2e2dc2d88b96f2ed274d2cef95aff3 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp >@@ -760,17 +760,15 @@ void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly() > syncCanvas(); > #endif > >- if (m_layerState.hasPendingChanges()) { >+ if (m_layerState.hasPendingChanges()) > m_coordinator->syncLayerState(m_id, m_layerState); >- resetLayerState(); >- } > > // Only unset m_movingVisibleRect after we have updated the visible rect after the animation stopped. > if (!hasActiveTransformAnimation) > m_movingVisibleRect = false; > } > >-void CoordinatedGraphicsLayer::resetLayerState() >+void CoordinatedGraphicsLayer::didCommitLayerState() > { > m_layerState.changeMask = 0; > m_layerState.tilesToCreate.clear(); >@@ -921,7 +919,11 @@ void CoordinatedGraphicsLayer::createTile(uint32_t tileID, const SurfaceUpdateIn > creationInfo.tileID = tileID; > creationInfo.scale = updateInfo.scaleFactor; > >- m_layerState.tilesToCreate.append(creationInfo); >+ CoordinatedGraphicsLayerState::TileCreationInfoSet::AddResult addResult = m_layerState.tilesToCreate.add(creationInfo); >+ if (!addResult.isNewEntry) { >+ m_layerState.tilesToUpdate.remove(tileID); >+ *addResult.iterator = creationInfo; >+ } > updateTile(tileID, updateInfo, tileRect); > } > >@@ -934,14 +936,40 @@ void CoordinatedGraphicsLayer::updateTile(uint32_t tileID, const SurfaceUpdateIn > tileUpdateInfo.tileID = tileID; > tileUpdateInfo.tileRect = tileRect; > tileUpdateInfo.updateInfo = updateInfo; >- m_layerState.tilesToUpdate.append(tileUpdateInfo); >+ >+ CoordinatedGraphicsLayerState::TileUpdateMap::AddResult addResult = m_layerState.tilesToUpdate.add(tileID, Vector<TileUpdateInfo>(1, tileUpdateInfo)); >+ if (!addResult.isNewEntry) { >+ // Remove old updates if imcompatible with or covered by the new one. >+ Vector<TileUpdateInfo> newUpdates; >+ Vector<TileUpdateInfo>& updates = addResult.iterator->value; >+ for (size_t i = 0; i < updates.size(); ++i) { >+ TileUpdateInfo& oldUpdate = updates[i]; >+ if (tileUpdateInfo.tileRect != oldUpdate.tileRect >+ || tileUpdateInfo.updateInfo.updateRect.contains(oldUpdate.updateInfo.updateRect)) >+ continue; >+ newUpdates.append(oldUpdate); >+ } >+ newUpdates.append(tileUpdateInfo); >+ updates.swap(newUpdates); >+ } > } > > void CoordinatedGraphicsLayer::removeTile(uint32_t tileID) > { > ASSERT(m_coordinator); > ASSERT(m_coordinator->isFlushingLayerChanges() || m_isPurging); >- m_layerState.tilesToRemove.append(tileID); >+ CoordinatedGraphicsLayerState::TileCreationInfoSet::iterator toCreateIt = m_layerState.tilesToCreate.find(tileID); >+ if (toCreateIt != m_layerState.tilesToCreate.end()) { >+ m_layerState.tilesToCreate.remove(toCreateIt); >+ m_layerState.tilesToUpdate.remove(tileID); >+ return; >+ } >+ >+ CoordinatedGraphicsLayerState::TileUpdateMap::iterator toUpdateIt = m_layerState.tilesToUpdate.find(tileID); >+ if (toUpdateIt != m_layerState.tilesToUpdate.end()) >+ m_layerState.tilesToUpdate.remove(toUpdateIt); >+ >+ m_layerState.tilesToRemove.add(tileID); > } > > void CoordinatedGraphicsLayer::updateContentBuffers() >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h >index 45bfb273d1dd447dac1a6d0018d0c3090f74e0a0..629811c48e454ebcee24942642f0e47ef7aa780b 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h >@@ -140,6 +140,7 @@ public: > virtual PassOwnPtr<GraphicsContext> beginContentUpdate(const IntSize&, uint32_t& atlasID, IntPoint&) OVERRIDE; > > void setCoordinator(CoordinatedGraphicsLayerClient*); >+ void didCommitLayerState(); > > void setNeedsVisibleRectAdjustment(); > void purgeBackingStores(); >@@ -174,7 +175,6 @@ private: > #endif > void didChangeImageBacking(); > >- void resetLayerState(); > void syncLayerState(); > void syncAnimations(); > void syncChildren(); >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsScene.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsScene.cpp >index eb085fc8ce43b747c559bd100ac507bdc03bc71f..f575f5cb5aa8135c9e0bc3fe80330ddeb5868400 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsScene.cpp >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsScene.cpp >@@ -486,8 +486,8 @@ void CoordinatedGraphicsScene::createTilesIfNeeded(GraphicsLayer* layer, const C > RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer); > ASSERT(backingStore); > >- for (size_t i = 0; i < state.tilesToCreate.size(); ++i) >- backingStore->createTile(state.tilesToCreate[i].tileID, state.tilesToCreate[i].scale); >+ for (CoordinatedGraphicsLayerState::TileCreationInfoSet::const_iterator it = state.tilesToCreate.begin(), end = state.tilesToCreate.end(); it != end; ++it) >+ backingStore->createTile(it->tileID, it->scale); > } > > void CoordinatedGraphicsScene::removeTilesIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state) >@@ -499,8 +499,8 @@ void CoordinatedGraphicsScene::removeTilesIfNeeded(GraphicsLayer* layer, const C > if (!backingStore) > return; > >- for (size_t i = 0; i < state.tilesToRemove.size(); ++i) >- backingStore->removeTile(state.tilesToRemove[i]); >+ for (HashSet<CoordinatedTileID>::const_iterator it = state.tilesToRemove.begin(), end = state.tilesToRemove.end(); it != end; ++it) >+ backingStore->removeTile(*it); > > m_backingStoresWithPendingBuffers.add(backingStore); > } >@@ -513,16 +513,17 @@ void CoordinatedGraphicsScene::updateTilesIfNeeded(GraphicsLayer* layer, const C > RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer); > ASSERT(backingStore); > >- for (size_t i = 0; i < state.tilesToUpdate.size(); ++i) { >- const TileUpdateInfo& tileInfo = state.tilesToUpdate[i]; >- const SurfaceUpdateInfo& surfaceUpdateInfo = tileInfo.updateInfo; >- >- SurfaceMap::iterator surfaceIt = m_surfaces.find(surfaceUpdateInfo.atlasID); >- ASSERT(surfaceIt != m_surfaces.end()); >- >- backingStore->updateTile(tileInfo.tileID, surfaceUpdateInfo.updateRect, tileInfo.tileRect, surfaceIt->value, surfaceUpdateInfo.surfaceOffset); >- m_backingStoresWithPendingBuffers.add(backingStore); >+ for (CoordinatedGraphicsLayerState::TileUpdateMap::const_iterator it = state.tilesToUpdate.begin(), end = state.tilesToUpdate.end(); it != end; ++it) { >+ const Vector<TileUpdateInfo>& updateInfos = it->value; >+ for (size_t i = 0; i < updateInfos.size(); ++i) { >+ const TileUpdateInfo& info = updateInfos[i]; >+ RefPtr<CoordinatedSurface> surface = m_surfaces.get(info.updateInfo.atlasID); >+ ASSERT(surface); >+ backingStore->updateTile(info.tileID, info.updateInfo.updateRect, info.tileRect, surface, info.updateInfo.surfaceOffset); >+ } > } >+ >+ m_backingStoresWithPendingBuffers.add(backingStore); > } > > void CoordinatedGraphicsScene::createUpdateAtlas(uint32_t atlasID, PassRefPtr<CoordinatedSurface> surface) >@@ -621,11 +622,11 @@ void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& > if (state.backgroundColor != m_backgroundColor) > setBackgroundColor(state.backgroundColor); > >- for (size_t i = 0; i < state.imagesToUpdate.size(); ++i) >- updateImageBacking(state.imagesToUpdate[i].first, state.imagesToUpdate[i].second); >+ for (CoordinatedGraphicsState::SurfaceUpdateMap::const_iterator it = state.imagesToUpdate.begin(), end = state.imagesToUpdate.end(); it != end; ++it) >+ updateImageBacking(it->key, it->value); > >- for (size_t i = 0; i < state.layersToUpdate.size(); ++i) >- setLayerState(state.layersToUpdate[i].first, state.layersToUpdate[i].second); >+ for (CoordinatedGraphicsState::LayerUpdateMap::const_iterator it = state.layersToUpdate.begin(), end = state.layersToUpdate.end(); it != end; ++it) >+ setLayerState(it->key, it->value); > > m_rootLayer->flushCompositingState(FloatRect()); > commitPendingBackingStoreOperations(); >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h >index 8caf90b961c417223ae06bce7eaeb8385e7a626d..1661a9e04924bdbdf62f893cf3f990cf792a7827 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsState.h >@@ -37,6 +37,8 @@ > #include "IntSize.h" > #include "SurfaceUpdateInfo.h" > #include "TransformationMatrix.h" >+#include <wtf/HashMap.h> >+#include <wtf/HashSet.h> > > #if ENABLE(CSS_FILTERS) > #include "FilterOperations.h" >@@ -50,6 +52,9 @@ namespace WebCore { > > class CoordinatedSurface; > >+typedef uint32_t CoordinatedTileID; >+enum { InvalidCoordinatedTileID = 0 }; >+ > typedef uint32_t CoordinatedLayerID; > enum { InvalidCoordinatedLayerID = 0 }; > >@@ -63,10 +68,38 @@ struct TileUpdateInfo { > }; > > struct TileCreationInfo { >- uint32_t tileID; >+ // Default scale argument is used for passing an id as key. >+ TileCreationInfo(CoordinatedTileID id = InvalidCoordinatedTileID, float scale = 0) >+ : tileID(id) >+ , scale(scale) >+ { } >+ >+ CoordinatedTileID tileID; > float scale; > }; > >+struct TileCreationInfoHash { >+ static unsigned hash(const TileCreationInfo& info) >+ { >+ ASSERT(info.tileID != InvalidCoordinatedTileID); >+ return WTF::intHash(info.tileID); >+ } >+ static bool equal(const TileCreationInfo& a, const TileCreationInfo& b) { return a.tileID == b.tileID; } >+ static const bool safeToCompareToEmptyOrDeleted = true; >+}; >+ >+struct TileCreationInfoHashTraits : WTF::GenericHashTraits<TileCreationInfo> { >+ static const bool emptyValueIsZero = true; >+ static const bool hasIsEmptyValueFunction = true; >+ static const bool needsDestruction = false; >+ static TileCreationInfo emptyValue() { return TileCreationInfo(InvalidCoordinatedTileID, 0); } >+ static bool isEmptyValue(const TileCreationInfo& value) { return value.tileID == InvalidCoordinatedTileID && !value.scale; } >+ static void constructEmtpyValue(TileCreationInfo& slot) { slot = emptyValue(); } >+ static TileCreationInfo deletedValue() { return TileCreationInfo(InvalidCoordinatedTileID, -1); } >+ static bool isDeletedValue(const TileCreationInfo& value) { return value.tileID == InvalidCoordinatedTileID && value.scale == -1; } >+ static void constructDeletedValue(TileCreationInfo& slot) { slot = deletedValue(); } >+}; >+ > struct CoordinatedGraphicsLayerState { > union { > struct { >@@ -149,14 +182,18 @@ struct CoordinatedGraphicsLayerState { > #endif > GraphicsLayerAnimations animations; > Vector<uint32_t> children; >- Vector<TileCreationInfo> tilesToCreate; >- Vector<uint32_t> tilesToRemove; >+ >+ typedef HashSet<TileCreationInfo, TileCreationInfoHash, TileCreationInfoHashTraits> TileCreationInfoSet; >+ TileCreationInfoSet tilesToCreate; >+ HashSet<CoordinatedTileID> tilesToRemove; >+ > CoordinatedLayerID replica; > CoordinatedLayerID mask; > CoordinatedImageBackingID imageID; > > unsigned repaintCount; >- Vector<TileUpdateInfo> tilesToUpdate; >+ typedef HashMap<CoordinatedTileID, Vector<TileUpdateInfo> > TileUpdateMap; >+ TileUpdateMap tilesToUpdate; > > #if USE(GRAPHICS_SURFACE) > IntSize canvasSize; >@@ -173,14 +210,16 @@ struct CoordinatedGraphicsLayerState { > }; > > struct CoordinatedGraphicsState { >- uint32_t rootCompositingLayer; >+ CoordinatedLayerID rootCompositingLayer; > Color backgroundColor; > FloatPoint scrollPosition; > IntSize contentsSize; > IntRect coveredRect; > >- Vector<std::pair<CoordinatedLayerID, CoordinatedGraphicsLayerState> > layersToUpdate; >- Vector<std::pair<CoordinatedImageBackingID, RefPtr<CoordinatedSurface> > > imagesToUpdate; >+ typedef HashMap<CoordinatedLayerID, CoordinatedGraphicsLayerState> LayerUpdateMap; >+ LayerUpdateMap layersToUpdate; >+ typedef HashMap<CoordinatedImageBackingID, RefPtr<CoordinatedSurface> > SurfaceUpdateMap; >+ SurfaceUpdateMap imagesToUpdate; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.cpp >index 364f06871082b58fcbd83a0ef31450be4800848b..60762d9925935154fff70312696b477698b01723 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.cpp >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.cpp >@@ -37,6 +37,8 @@ UpdateAtlas::UpdateAtlas(UpdateAtlasClient* client, int dimension, CoordinatedSu > m_ID = ++nextID; > IntSize size = nextPowerOfTwo(IntSize(dimension, dimension)); > m_surface = CoordinatedSurface::create(size, flags); >+ m_areaAllocator = adoptPtr(new GeneralAreaAllocator(this->size())); >+ m_areaAllocator->setMinimumAllocation(IntSize(32, 32)); > > // FIXME: Currently, if sending the message fails, UpdateAtlas gives up drawing anything implicitly. > if (!m_client->createUpdateAtlas(m_ID, m_surface)) >@@ -49,23 +51,24 @@ UpdateAtlas::~UpdateAtlas() > m_client->removeUpdateAtlas(m_ID); > } > >-void UpdateAtlas::buildLayoutIfNeeded() >+void UpdateAtlas::didCommitBuffers() > { >- if (!m_areaAllocator) { >- m_areaAllocator = adoptPtr(new GeneralAreaAllocator(size())); >- m_areaAllocator->setMinimumAllocation(IntSize(32, 32)); >- } >+ m_hasCommittedOnce = true; >+ m_areaAllocator->markAllocations(); > } > > void UpdateAtlas::didSwapBuffers() > { >- m_areaAllocator.clear(); >+ // Do not release allocations if this is a new atlas that has never been committed yet. >+ if (!m_hasCommittedOnce) >+ return; >+ >+ m_areaAllocator->clearMarkedAllocations(); > } > > PassOwnPtr<GraphicsContext> UpdateAtlas::beginPaintingOnAvailableBuffer(uint32_t& atlasID, const IntSize& size, IntPoint& offset) > { > m_inactivityInSeconds = 0; >- buildLayoutIfNeeded(); > IntRect rect = m_areaAllocator->allocate(size); > > // No available buffer was found, returning null. >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.h b/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.h >index 48a6bf844a490f7fd2c39a0424e330fddb16d78b..6e33a760d2e5f080587e9c44fadf76723e01940b 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.h >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/UpdateAtlas.h >@@ -47,6 +47,7 @@ public: > > // Returns a null pointer of there is no available buffer. > PassOwnPtr<GraphicsContext> beginPaintingOnAvailableBuffer(uint32_t& atlasID, const IntSize&, IntPoint& offset); >+ void didCommitBuffers(); > void didSwapBuffers(); > bool supportsAlpha() const { return m_surface->supportsAlpha(); } > >@@ -60,7 +61,7 @@ public: > const double inactiveSecondsTolerance = 3; > return m_inactivityInSeconds > inactiveSecondsTolerance; > } >- bool isInUse() const { return m_areaAllocator; } >+ bool isInUse() const { return m_areaAllocator->hasAllocations(); } > > private: > void buildLayoutIfNeeded(); >@@ -71,6 +72,7 @@ private: > RefPtr<CoordinatedSurface> m_surface; > double m_inactivityInSeconds; > uint32_t m_ID; >+ bool m_hasCommittedOnce; > }; > > } // namespace WebCore >diff --git a/Source/WebKit2/Platform/CoreIPC/ArgumentCoders.h b/Source/WebKit2/Platform/CoreIPC/ArgumentCoders.h >index 6c8241e71a15b98b18e6b2dcddfc4c935fc3ee14..5814a3d9536cd19bf2668ee0fe2fafb6310eaf3a 100644 >--- a/Source/WebKit2/Platform/CoreIPC/ArgumentCoders.h >+++ b/Source/WebKit2/Platform/CoreIPC/ArgumentCoders.h >@@ -31,6 +31,7 @@ > #include <utility> > #include <wtf/Forward.h> > #include <wtf/HashMap.h> >+#include <wtf/HashSet.h> > #include <wtf/TypeTraits.h> > #include <wtf/Vector.h> > >@@ -157,6 +158,40 @@ template<typename T> struct VectorArgumentCoder<true, T> { > > template<typename T> struct ArgumentCoder<Vector<T> > : VectorArgumentCoder<WTF::IsArithmetic<T>::value, T> { }; > >+template<typename ValueArg, typename HashArg, typename TraitsArg> >+struct ArgumentCoder<HashSet<ValueArg, HashArg, TraitsArg> > { >+ typedef HashSet<ValueArg, HashArg, TraitsArg> HashSetType; >+ >+ static void encode(ArgumentEncoder &encoder, const HashSetType& hashSet) >+ { >+ encoder << uint64_t(hashSet.size()); >+ for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it) >+ encoder << *it; >+ } >+ >+ static bool decode(ArgumentDecoder& decoder, HashSetType& hashSet) >+ { >+ uint64_t size; >+ if (!decoder.decode(size)) >+ return false; >+ >+ HashSetType tempHashSet; >+ for (uint64_t i = 0; i < size; ++i) { >+ ValueArg value; >+ if (!decoder.decode(value)) >+ return false; >+ if (!tempHashSet.add(value).isNewEntry) { >+ // Inconsistent set, bail. >+ decoder.markInvalid(); >+ return false; >+ } >+ } >+ >+ hashSet.swap(tempHashSet); >+ return true; >+ } >+}; >+ > template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct ArgumentCoder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { > typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType; > >diff --git a/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp b/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp >index c78cb1b05eb37c88f8af2a1366e555f940937f9d..9ce4093fb4aaf116f584beb788536fd9c504b79e 100644 >--- a/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp >+++ b/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp >@@ -1023,16 +1023,13 @@ void ArgumentCoder<CoordinatedGraphicsState>::encode(ArgumentEncoder& encoder, c > // That's why we cannot use simple std::pair encoder. > encoder << static_cast<uint64_t>(state.imagesToUpdate.size()); > >- typedef Vector<std::pair<CoordinatedImageBackingID, RefPtr<CoordinatedSurface> > > SurfaceUpdatePairVector; >- SurfaceUpdatePairVector::const_iterator end = state.imagesToUpdate.end(); >- for (SurfaceUpdatePairVector::const_iterator it = state.imagesToUpdate.begin(); it != end; ++it) { >- >- WebCoordinatedSurface* webCoordinatedSurface = static_cast<WebCoordinatedSurface*>(it->second.get()); >+ for (CoordinatedGraphicsState::SurfaceUpdateMap::const_iterator it = state.imagesToUpdate.begin(), end = state.imagesToUpdate.end(); it != end; ++it) { >+ WebCoordinatedSurface* webCoordinatedSurface = static_cast<WebCoordinatedSurface*>(it->value.get()); > WebCoordinatedSurface::Handle handle; > if (!webCoordinatedSurface->createHandle(handle)) > return; > >- encoder << it->first; >+ encoder << it->key; > encoder << handle; > } > } >@@ -1071,7 +1068,9 @@ bool ArgumentCoder<CoordinatedGraphicsState>::decode(ArgumentDecoder& decoder, C > return false; > > RefPtr<CoordinatedSurface> surface = WebCoordinatedSurface::create(handle); >- state.imagesToUpdate.append(std::make_pair(imageID, surface.release())); >+ CoordinatedGraphicsState::SurfaceUpdateMap::AddResult addResult = state.imagesToUpdate.add(imageID, surface.release()); >+ if (!addResult.isNewEntry) >+ return false; > } > > return true; >diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp >index 3e470a13cb08703763af7916c0abe584c9a23ce8..0d67f6f44b1a215f70aaa1f663531da17c64e1a5 100644 >--- a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp >+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp >@@ -85,6 +85,9 @@ CoordinatedLayerTreeHost::CoordinatedLayerTreeHost(WebPage* webPage) > , m_isFlushingLayerChanges(false) > , m_waitingForUIProcess(true) > , m_isSuspended(false) >+ , m_useDoubleBuffering(true) // FIXME: Currently it will stay enabled forerev. We should disable it on low memory situations. >+ , m_didRenderFrameInBackBuffers(false) >+ , m_shouldServiceScriptedAnimations(true) > , m_shouldSyncFrame(false) > , m_didInitializeRootCompositingLayer(false) > , m_layerFlushTimer(this, &CoordinatedLayerTreeHost::layerFlushTimerFired) >@@ -146,6 +149,12 @@ void CoordinatedLayerTreeHost::scheduleLayerFlush() > if (!m_layerFlushSchedulingEnabled) > return; > >+ // Invalidate prerendered frame. requestAnimationFrame callbacks should be synchronised >+ // to the UI frame rate so we won't call them until we hear from the UI process. >+ if (m_didRenderFrameInBackBuffers) >+ m_shouldServiceScriptedAnimations = false; >+ m_didRenderFrameInBackBuffers = false; >+ > if (!m_layerFlushTimer.isActive()) > m_layerFlushTimer.startOneShot(0); > } >@@ -283,11 +292,23 @@ void CoordinatedLayerTreeHost::setPageOverlayOpacity(PageOverlay*, float value) > scheduleLayerFlush(); > } > >+bool CoordinatedLayerTreeHost::shouldFlushLayerChanges() >+{ >+ if (m_useDoubleBuffering) >+ return !m_didRenderFrameInBackBuffers; >+ >+ return !m_waitingForUIProcess; >+} >+ > bool CoordinatedLayerTreeHost::flushPendingLayerChanges() > { >- if (m_waitingForUIProcess) >+ if (!shouldFlushLayerChanges()) > return false; > >+ ASSERT(!m_isFlushingLayerChanges); >+ ASSERT(!m_didRenderFrameInBackBuffers); >+ ASSERT(!m_waitingForUIProcess || m_useDoubleBuffering); >+ > TemporaryChange<bool> protector(m_isFlushingLayerChanges, true); > > createCompositingLayers(); >@@ -305,20 +326,13 @@ bool CoordinatedLayerTreeHost::flushPendingLayerChanges() > > deleteCompositingLayers(); > >- if (m_shouldSyncFrame) { >+ if (m_waitingForUIProcess) >+ m_didRenderFrameInBackBuffers = true; >+ else if (m_shouldSyncFrame) { > didSync = true; >- >- m_state.contentsSize = roundedIntSize(m_nonCompositedContentLayer->size()); >- m_state.coveredRect = toCoordinatedGraphicsLayer(m_nonCompositedContentLayer.get())->coverRect(); >- m_state.scrollPosition = m_visibleContentsRect.location(); >- >- m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::CommitCoordinatedGraphicsState(m_state)); >- >- m_state.layersToUpdate.clear(); >- m_state.imagesToUpdate.clear(); >- >- m_waitingForUIProcess = true; >- m_shouldSyncFrame = false; >+ commitFrame(); >+ if (m_useDoubleBuffering && !m_layerFlushTimer.isActive()) >+ m_layerFlushTimer.startOneShot(0); > } else > unlockAnimations(); > >@@ -330,6 +344,28 @@ bool CoordinatedLayerTreeHost::flushPendingLayerChanges() > return didSync; > } > >+void CoordinatedLayerTreeHost::commitFrame() >+{ >+ m_state.contentsSize = roundedIntSize(m_nonCompositedContentLayer->size()); >+ m_state.coveredRect = toCoordinatedGraphicsLayer(m_nonCompositedContentLayer.get())->coverRect(); >+ m_state.scrollPosition = m_visibleContentsRect.location(); >+ >+ m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::CommitCoordinatedGraphicsState(m_state)); >+ >+ m_state.layersToUpdate.clear(); >+ m_state.imagesToUpdate.clear(); >+ >+ m_waitingForUIProcess = true; >+ m_didRenderFrameInBackBuffers = false; >+ m_shouldSyncFrame = false; >+ >+ for (size_t i = 0; i < m_updateAtlases.size(); ++i) >+ m_updateAtlases[i]->didCommitBuffers(); >+ >+ for (LayerMap::iterator it = m_registeredLayers.begin(); it != m_registeredLayers.end(); ++it) >+ toCoordinatedGraphicsLayer(it->value)->didCommitLayerState(); >+} >+ > void CoordinatedLayerTreeHost::createCompositingLayers() > { > if (m_layersToCreate.isEmpty()) >@@ -382,7 +418,7 @@ void CoordinatedLayerTreeHost::syncLayerState(CoordinatedLayerID id, Coordinated > prepareCustomFilterProxiesIfNeeded(state); > #endif > >- m_state.layersToUpdate.append(std::make_pair(id, state)); >+ m_state.layersToUpdate.set(id, state); > } > > #if ENABLE(CSS_SHADERS) >@@ -481,7 +517,7 @@ void CoordinatedLayerTreeHost::unlockAnimations() > > void CoordinatedLayerTreeHost::performScheduledLayerFlush() > { >- if (m_isSuspended || m_waitingForUIProcess) >+ if (m_isSuspended || !shouldFlushLayerChanges()) > return; > > // We lock the animations while performing layout, to avoid flickers caused by animations continuing in the UI process while >@@ -505,8 +541,10 @@ void CoordinatedLayerTreeHost::performScheduledLayerFlush() > void CoordinatedLayerTreeHost::syncDisplayState() > { > #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER) && !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) >- // Make sure that any previously registered animation callbacks are being executed before we flush the layers. >- m_webPage->corePage()->mainFrame()->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime())); >+ if (m_shouldServiceScriptedAnimations) { >+ // Make sure that any previously registered animation callbacks are being executed before we flush the layers. >+ m_webPage->corePage()->mainFrame()->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime())); >+ } > #endif > > m_webPage->layoutIfNeeded(); >@@ -575,7 +613,7 @@ bool CoordinatedLayerTreeHost::updateImageBacking(CoordinatedImageBackingID imag > if (!webCoordinatedSurface->createHandle(handle)) > return false; > >- m_state.imagesToUpdate.append(std::make_pair(imageID, coordinatedSurface)); >+ m_state.imagesToUpdate.set(imageID, coordinatedSurface); > return true; > } > >@@ -731,9 +769,16 @@ void CoordinatedLayerTreeHost::animationFrameReady() > void CoordinatedLayerTreeHost::renderNextFrame() > { > m_waitingForUIProcess = false; >- scheduleLayerFlush(); >+ m_shouldServiceScriptedAnimations = true; >+ > for (unsigned i = 0; i < m_updateAtlases.size(); ++i) > m_updateAtlases[i]->didSwapBuffers(); >+ >+ if (m_didRenderFrameInBackBuffers && m_shouldSyncFrame) >+ commitFrame(); >+ >+ m_didRenderFrameInBackBuffers = false; >+ scheduleLayerFlush(); > } > > void CoordinatedLayerTreeHost::purgeBackingStores() >diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h >index b07edc140adc928a349de5a5c9cefb16e08deb11..65b686a1b5c8fd21eb12e3d6bfda41b9e3c6c2b9 100644 >--- a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h >+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h >@@ -144,6 +144,8 @@ private: > void syncDisplayState(); > void lockAnimations(); > void unlockAnimations(); >+ void commitFrame(); >+ bool shouldFlushLayerChanges(); > > void layerFlushTimerFired(WebCore::Timer<CoordinatedLayerTreeHost>*); > >@@ -195,6 +197,11 @@ private: > > bool m_waitingForUIProcess; > bool m_isSuspended; >+ >+ bool m_useDoubleBuffering; >+ bool m_didRenderFrameInBackBuffers; >+ bool m_shouldServiceScriptedAnimations; >+ > WebCore::FloatRect m_visibleContentsRect; > > LayerTreeContext m_layerTreeContext;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 109579
:
187859
|
187860
|
187861
|
193815
|
194567
|
196015
|
196150