From 989f2afb7cc3144f3dd492a6fabd35390730e87f Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 8 Apr 2011 11:41:20 -0700 Subject: 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 --- WebCore/platform/graphics/android/BaseTile.cpp | 53 +++++++++++--------------- WebCore/platform/graphics/android/BaseTile.h | 1 - 2 files changed, 23 insertions(+), 31 deletions(-) (limited to 'WebCore') 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 -- cgit v1.1