diff options
author | Nicolas Roard <nicolasroard@google.com> | 2011-08-04 17:02:40 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-08-04 17:02:40 -0700 |
commit | 6b9d05281a529f9cd3e527fb8d657b338bb4fd7a (patch) | |
tree | f02156683e0f741e226d59d3d4db4e4cdfbb4604 /Source/WebCore | |
parent | bd7014f80539c945baa9bdad996b24ee02545963 (diff) | |
parent | 8c8109615ff2d833bbcf6866e935e91188c00556 (diff) | |
download | external_webkit-6b9d05281a529f9cd3e527fb8d657b338bb4fd7a.zip external_webkit-6b9d05281a529f9cd3e527fb8d657b338bb4fd7a.tar.gz external_webkit-6b9d05281a529f9cd3e527fb8d657b338bb4fd7a.tar.bz2 |
Merge "Fixes layers painting crashes"
Diffstat (limited to 'Source/WebCore')
10 files changed, 80 insertions, 10 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp index cafab4a..d73c30f 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp @@ -127,6 +127,7 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height()); canvas.scale(renderInfo.scale, renderInfo.scale); unsigned int pictureCount = 0; + renderInfo.tilePainter->beginPaint(); renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas, &pictureCount); if (renderInfo.baseTile->isLayerTile()) renderInfo.tilePainter->paintExtra(&canvas); @@ -155,6 +156,7 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) drawTileInfo(&canvas, renderInfo, pictureCount); } renderInfo.textureInfo->m_pictureCount = pictureCount; + renderInfo.tilePainter->endPaint(); renderingComplete(renderInfo, &canvas); return pictureCount; } diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp index 8abd250..d5623df 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp @@ -25,15 +25,18 @@ #include "config.h" #include "PaintTileOperation.h" +#include "LayerAndroid.h" namespace WebCore { -PaintTileOperation::PaintTileOperation(BaseTile* tile) +PaintTileOperation::PaintTileOperation(BaseTile* tile, LayerAndroid* layer) : QueuedOperation(QueuedOperation::PaintTile, tile->page()) , m_tile(tile) + , m_layer(layer) { if (m_tile) m_tile->setRepaintPending(true); + SkSafeRef(m_layer); } PaintTileOperation::~PaintTileOperation() @@ -42,6 +45,7 @@ PaintTileOperation::~PaintTileOperation() m_tile->setRepaintPending(false); m_tile = 0; } + SkSafeUnref(m_layer); } bool PaintTileOperation::operator==(const QueuedOperation* operation) diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/PaintTileOperation.h index f5c73f5..4d1bb1a 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h @@ -30,9 +30,11 @@ namespace WebCore { +class LayerAndroid; + class PaintTileOperation : public QueuedOperation { public: - PaintTileOperation(BaseTile* tile); + PaintTileOperation(BaseTile* tile, LayerAndroid* layer = 0); virtual ~PaintTileOperation(); virtual bool operator==(const QueuedOperation* operation); virtual void run(); @@ -42,6 +44,7 @@ public: private: BaseTile* m_tile; + LayerAndroid* m_layer; }; class ScaleFilter : public OperationFilter { diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp index a364392..fe7044c 100644 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp +++ b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp @@ -49,8 +49,15 @@ namespace WebCore { +bool PaintedSurface::busy() +{ + android::Mutex::Autolock lock(m_layerLock); + return m_busy; +} + void PaintedSurface::removeLayer(LayerAndroid* layer) { + android::Mutex::Autolock lock(m_layerLock); if (m_layer != layer) return; m_layer = 0; @@ -58,6 +65,7 @@ void PaintedSurface::removeLayer(LayerAndroid* layer) void PaintedSurface::replaceLayer(LayerAndroid* layer) { + android::Mutex::Autolock lock(m_layerLock); if (!layer) return; @@ -114,21 +122,44 @@ bool PaintedSurface::draw() return askRedraw; } +void PaintedSurface::beginPaint() +{ + m_layerLock.lock(); + m_busy = true; + m_layerLock.unlock(); +} + +void PaintedSurface::endPaint() +{ + m_layerLock.lock(); + m_busy = false; + m_layerLock.unlock(); +} + bool PaintedSurface::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) { - if (!m_layer) + m_layerLock.lock(); + LayerAndroid* layer = m_layer; + m_layerLock.unlock(); + + if (!layer) return false; - m_layer->contentDraw(canvas); - m_pictureUsed = m_layer->pictureUsed(); + layer->contentDraw(canvas); + m_pictureUsed = layer->pictureUsed(); *pictureUsed = m_pictureUsed; + return true; } void PaintedSurface::paintExtra(SkCanvas* canvas) { - if (m_layer) - m_layer->extraDraw(canvas); + m_layerLock.lock(); + LayerAndroid* layer = m_layer; + m_layerLock.unlock(); + + if (layer) + layer->extraDraw(canvas); } float PaintedSurface::opacity() { diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h index e95662d..39d6154 100644 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.h +++ b/Source/WebCore/platform/graphics/android/PaintedSurface.h @@ -47,6 +47,7 @@ public: , m_tiledTexture(0) , m_scale(0) , m_pictureUsed(0) + , m_busy(false) { TilesManager::instance()->addPaintedSurface(this); #ifdef DEBUG_COUNT @@ -69,6 +70,7 @@ public: bool paint(SkCanvas*); void removeLayer(LayerAndroid* layer); void replaceLayer(LayerAndroid* layer); + bool busy(); bool owns(BaseTileTexture* texture); @@ -78,6 +80,8 @@ public: virtual bool paint(BaseTile*, SkCanvas*, unsigned int*); virtual void paintExtra(SkCanvas*); virtual const TransformationMatrix* transform(); + virtual void beginPaint(); + virtual void endPaint(); // used by TiledTexture const IntRect& area() { return m_area; } @@ -96,6 +100,10 @@ private: float m_scale; unsigned int m_pictureUsed; + + bool m_busy; + + android::Mutex m_layerLock; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index 191edf3..31034e3 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -40,6 +40,8 @@ public: virtual bool paint(BaseTile* tile, SkCanvas*, unsigned int*) = 0; virtual void paintExtra(SkCanvas*) = 0; virtual const TransformationMatrix* transform() { return 0; } + virtual void beginPaint() = 0; + virtual void endPaint() = 0; }; } diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h index 078ce48..4b09364 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.h +++ b/Source/WebCore/platform/graphics/android/TiledPage.h @@ -68,6 +68,8 @@ public: // used by individual tiles to generate the bitmap for their tile bool paint(BaseTile*, SkCanvas*, unsigned int*); void paintExtra(SkCanvas*); + void beginPaint() {} + void endPaint() {} // used by individual tiles to get the information about the current picture GLWebViewState* glWebViewState() { return m_glWebViewState; } diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index 66846fe..a49c6c6 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -56,6 +56,9 @@ void TiledTexture::prepare(GLWebViewState* state, bool repaint) if (!m_surface) return; + if (!m_surface->layer()) + return; + // first, how many tiles do we need IntRect visibleArea = m_surface->visibleArea(); IntRect area(visibleArea.x() * m_surface->scale(), @@ -134,8 +137,9 @@ void TiledTexture::prepareTile(bool repaint, int x, int y) if (repaint || tile->isDirty()) schedule = true; - if (schedule && !tile->isRepaintPending()) { - PaintTileOperation *operation = new PaintTileOperation(tile); + LayerAndroid* layer = m_surface->layer(); + if (schedule && layer && !tile->isRepaintPending()) { + PaintTileOperation *operation = new PaintTileOperation(tile, layer); TilesManager::instance()->scheduleOperation(operation); } } @@ -210,6 +214,18 @@ const TransformationMatrix* TiledTexture::transform() return m_surface->transform(); } +void TiledTexture::beginPaint() +{ + if (m_surface) + m_surface->beginPaint(); +} + +void TiledTexture::endPaint() +{ + if (m_surface) + m_surface->endPaint(); +} + void TiledTexture::removeTiles() { TilesManager::instance()->removeOperationsForPainter(this, true); diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h index b6d5b4c..532cc2c 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.h +++ b/Source/WebCore/platform/graphics/android/TiledTexture.h @@ -74,6 +74,8 @@ public: bool paint(BaseTile* tile, SkCanvas*, unsigned int*); virtual void paintExtra(SkCanvas*); virtual const TransformationMatrix* transform(); + virtual void beginPaint(); + virtual void endPaint(); private: PaintedSurface* m_surface; diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index b99cbfc..bf14c61 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -204,7 +204,7 @@ void TilesManager::cleanupTilesTextures() WTF::Vector<PaintedSurface*> collect; for (unsigned int i = 0; i < m_paintedSurfaces.size(); i++) { PaintedSurface* surface = m_paintedSurfaces[i]; - if (!surface->layer()) + if (!surface->layer() && !surface->busy()) collect.append(surface); } XLOG("remove %d / %d PaintedSurfaces", collect.size(), m_paintedSurfaces.size()); |