diff options
author | Nicolas Roard <nicolasroard@google.com> | 2011-12-16 20:05:07 -0800 |
---|---|---|
committer | Nicolas Roard <nicolasroard@google.com> | 2012-01-03 10:48:53 -0800 |
commit | 61e0d189f2b74650bf72a6a2820f66a8b17c3d06 (patch) | |
tree | e131cc1d57c9fc94c461bb36ffb132cb0235f2c4 /Source/WebCore/platform/graphics/android | |
parent | 599c05f3080acd1c99f4d925c333d8a2711c9bdf (diff) | |
download | external_webkit-61e0d189f2b74650bf72a6a2820f66a8b17c3d06.zip external_webkit-61e0d189f2b74650bf72a6a2820f66a8b17c3d06.tar.gz external_webkit-61e0d189f2b74650bf72a6a2820f66a8b17c3d06.tar.bz2 |
Fix crash with composited layers - DO NOT MERGE
Cherry-pick from master
When we have composited layers inside iframes/frames, the layers
hierarchy is not always up to date at the time of the layerSync()
call. If some of those layers are scheduled to be repainted, the
repaint operation will triggers the update of the composited layers
tree -- possibly resulting in the deallocation of the very same
GraphicsLayer we were painting from, and thus leading to a crash.
The fix consist in gathering all the root RenderLayer (for each
frame containing composited layers) and explicitely asking
RenderLayerCompositor to check if the composited tree needs to be
updated, before we traverse the tree to paint the elements.
bug:5695185
Change-Id: I33a00b847eb19c9aa4b68f0ac3adbe36709ed00b
Diffstat (limited to 'Source/WebCore/platform/graphics/android')
-rw-r--r-- | Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp | 34 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h | 2 |
2 files changed, 33 insertions, 3 deletions
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index 6990503..567b54b 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -963,11 +963,31 @@ void GraphicsLayerAndroid::syncMask() } } -void GraphicsLayerAndroid::syncCompositingState() +void GraphicsLayerAndroid::gatherRootLayers(Vector<const RenderLayer*>& list) { - for (unsigned int i = 0; i < m_children.size(); i++) - m_children[i]->syncCompositingState(); + RenderLayer* renderLayer = renderLayerFromClient(m_client); + if (renderLayer) { + const RenderLayer* rootLayer = renderLayer->root(); + bool found = false; + for (unsigned int i = 0; i < list.size(); i++) { + const RenderLayer* current = list[i]; + if (current == rootLayer) { + found = true; + break; + } + } + if (!found) + list.append(rootLayer); + } + for (unsigned int i = 0; i < m_children.size(); i++) { + GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); + layer->gatherRootLayers(list); + } +} + +void GraphicsLayerAndroid::syncCompositingStateForThisLayerOnly() +{ updateScrollingLayers(); updateFixedPosition(); syncChildren(); @@ -977,6 +997,14 @@ void GraphicsLayerAndroid::syncCompositingState() repaint(); } +void GraphicsLayerAndroid::syncCompositingState() +{ + for (unsigned int i = 0; i < m_children.size(); i++) + m_children[i]->syncCompositingState(); + + syncCompositingStateForThisLayerOnly(); +} + void GraphicsLayerAndroid::notifyClientAnimationStarted() { for (unsigned int i = 0; i < m_children.size(); i++) diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 358f674..e6d75b0 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -116,7 +116,9 @@ public: virtual void setZPosition(float); + void gatherRootLayers(Vector<const RenderLayer*>&); virtual void syncCompositingState(); + virtual void syncCompositingStateForThisLayerOnly(); void notifyClientAnimationStarted(); LayerAndroid* contentLayer() { return m_contentLayer; } |