diff options
author | John Reck <jreck@google.com> | 2011-04-08 11:41:20 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2011-05-05 14:32:12 -0700 |
commit | 989f2afb7cc3144f3dd492a6fabd35390730e87f (patch) | |
tree | 57f26b488e3893e2ac81304821142670211881af | |
parent | 2d60bef786645e5b9e2da0e8374d3f06a40d0638 (diff) | |
download | external_webkit-989f2afb7cc3144f3dd492a6fabd35390730e87f.zip external_webkit-989f2afb7cc3144f3dd492a6fabd35390730e87f.tar.gz external_webkit-989f2afb7cc3144f3dd492a6fabd35390730e87f.tar.bz2 |
DO NOT MERGE ANR fix
Race condition in BaseTile could cause a texture's owner to change
to a BaseTile, without that BaseTile actually using that texture. This
could cause two texture's to point to the same BaseTile.
Bug: 4268381
Change-Id: I66b38a042e66fc32f4e098428d1f4a537d76a9d8
-rw-r--r-- | WebCore/platform/graphics/android/BaseTile.cpp | 53 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseTile.h | 1 |
2 files changed, 23 insertions, 31 deletions
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp index d58c549..25ba60f 100644 --- a/WebCore/platform/graphics/android/BaseTile.cpp +++ b/WebCore/platform/graphics/android/BaseTile.cpp @@ -70,7 +70,6 @@ BaseTile::BaseTile() , m_lastDirtyPicture(0) , m_fullRepaintA(true) , m_fullRepaintB(true) - , m_painting(false) , m_lastPaintedPicture(0) { #ifdef DEBUG_COUNT @@ -105,8 +104,7 @@ void BaseTile::reserveTexture() BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this); android::AutoMutex lock(m_atomicSync); - if (texture && !m_painting && - m_texture != texture) { + if (texture && m_texture != texture) { m_lastPaintedPicture = 0; fullInval(); m_texture = texture; @@ -118,8 +116,6 @@ bool BaseTile::removeTexture(BackedDoubleBufferedTexture* texture) XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page); // We update atomically, so paintBitmap() can see the correct value android::AutoMutex lock(m_atomicSync); - if (m_painting) - return false; if (m_texture == texture) m_texture = 0; return true; @@ -261,14 +257,12 @@ void BaseTile::paintBitmap() bool dirty = m_dirty; BackedDoubleBufferedTexture* texture = m_texture; SkRegion dirtyArea = *m_currentDirtyArea; - m_painting = true; float scale = m_scale; const int x = m_x; const int y = m_y; m_atomicSync.unlock(); if (!dirty || !texture) { - m_painting = false; return; } @@ -281,7 +275,6 @@ void BaseTile::paintBitmap() // transferred to another BaseTile under us) if (texture->owner() != this || texture->usedLevel() > 1) { texture->producerRelease(); - m_painting = false; return; } @@ -359,40 +352,40 @@ void BaseTile::paintBitmap() texture->setTile(textureInfo, x, y, scale, pictureCount); texture->producerReleaseAndSwap(); - m_lastPaintedPicture = pictureCount; - - // set the fullrepaint flags + if (texture == m_texture) { + m_lastPaintedPicture = pictureCount; - if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA) - m_fullRepaintA = false; + // set the fullrepaint flags - if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB) - m_fullRepaintB = false; + if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA) + m_fullRepaintA = false; - // The various checks to see if we are still dirty... + if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB) + m_fullRepaintB = false; - m_dirty = false; + // The various checks to see if we are still dirty... - if (m_scale != scale) - m_dirty = true; + m_dirty = false; - if (!fullRepaint) - m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op); + if (m_scale != scale) + m_dirty = true; - if (!m_currentDirtyArea->isEmpty()) - m_dirty = true; + if (!fullRepaint) + m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op); - // Now we can swap the dirty areas + if (!m_currentDirtyArea->isEmpty()) + m_dirty = true; - m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA; + // Now we can swap the dirty areas - if (!m_currentDirtyArea->isEmpty()) - m_dirty = true; + m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA; - if (!m_dirty) - m_usable = true; + if (!m_currentDirtyArea->isEmpty()) + m_dirty = true; - m_painting = false; + if (!m_dirty) + m_usable = true; + } m_atomicSync.unlock(); } diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h index b832eee..63ce117 100644 --- a/WebCore/platform/graphics/android/BaseTile.h +++ b/WebCore/platform/graphics/android/BaseTile.h @@ -127,7 +127,6 @@ private: bool m_fullRepaintA; bool m_fullRepaintB; SkRegion* m_currentDirtyArea; - bool m_painting; // stores the id of the latest picture painted to the tile. If the id is 0 // then we know that the picture has not yet been painted an there is nothing |