diff options
Diffstat (limited to 'Source/WebCore')
12 files changed, 328 insertions, 102 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 1250d91..5d1273b 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -678,6 +678,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/TiledPage.cpp \ platform/graphics/android/TiledTexture.cpp \ platform/graphics/android/TransferQueue.cpp \ + platform/graphics/android/UpdateManager.cpp \ platform/graphics/android/VideoLayerAndroid.cpp \ platform/graphics/android/VideoLayerManager.cpp \ platform/graphics/android/ZoomManager.cpp \ diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp index 68af1d6..96599af 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp @@ -132,7 +132,6 @@ 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); @@ -161,7 +160,6 @@ 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/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 4a15f9f..318a969 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -305,6 +305,14 @@ bool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight, return true; } +bool BaseTile::isTileVisible(const IntRect& viewTileBounds) +{ + return (m_x >= viewTileBounds.x() + && m_x < viewTileBounds.x() + viewTileBounds.width() + && m_y >= viewTileBounds.y() + && m_y < viewTileBounds.y() + viewTileBounds.height()); +} + // This is called from the texture generation thread void BaseTile::paintBitmap() { diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h index 6d0fa8f..27fffc6 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.h +++ b/Source/WebCore/platform/graphics/android/BaseTile.h @@ -109,6 +109,7 @@ public: bool intersectWithRect(int x, int y, int tileWidth, int tileHeight, float scale, const SkRect& dirtyRect, SkRect& realTileRect); + bool isTileVisible(const IntRect& viewTileBounds); void markAsDirty(const unsigned int pictureCount, const SkRegion& dirtyArea); diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp index 8a4c072..1eb51c7 100644 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp +++ b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp @@ -26,17 +26,21 @@ #include "config.h" #include "PaintedSurface.h" + #include "LayerAndroid.h" #include "TilesManager.h" #include "SkCanvas.h" #include "SkPicture.h" -#ifdef DEBUG - #include <cutils/log.h> #include <wtf/CurrentTime.h> #include <wtf/text/CString.h> +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__) + +#ifdef DEBUG + #undef XLOG #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__) @@ -60,12 +64,6 @@ PaintedSurface::~PaintedSurface() delete m_tiledTexture; } -bool PaintedSurface::busy() -{ - android::Mutex::Autolock lock(m_layerLock); - return m_busy; -} - void PaintedSurface::removeLayer() { android::Mutex::Autolock lock(m_layerLock); @@ -96,6 +94,8 @@ void PaintedSurface::replaceLayer(LayerAndroid* layer) SkSafeRef(layer); SkSafeUnref(m_layer); m_layer = layer; + if (layer && layer->picture()) + m_updateManager.updatePicture(layer->picture()); } void PaintedSurface::prepare(GLWebViewState* state) @@ -106,6 +106,18 @@ void PaintedSurface::prepare(GLWebViewState* state) if (!m_layer->needsTexture()) return; + bool startFastSwap = false; + if (state->isScrolling()) { + // when scrolling, block updates and swap tiles as soon as they're ready + startFastSwap = true; + } else { + // when not, push updates down to TiledTexture in every prepare + m_updateManager.swap(); + m_tiledTexture->update(m_updateManager.getPaintingInval(), + m_updateManager.getPaintingPicture()); + m_updateManager.clearPaintingInval(); + } + XLOG("prepare layer %d %x at scale %.2f", m_layer->uniqueId(), m_layer, m_layer->getScale()); @@ -128,7 +140,7 @@ void PaintedSurface::prepare(GLWebViewState* state) XLOG("layer %d %x prepared at size (%d, %d) @ scale %.2f", m_layer->uniqueId(), m_layer, w, h, scale); - m_tiledTexture->prepare(state, m_pictureUsed != m_layer->pictureUsed()); + m_tiledTexture->prepare(state, m_pictureUsed != m_layer->pictureUsed(), startFastSwap); } bool PaintedSurface::draw() @@ -139,44 +151,13 @@ bool PaintedSurface::draw() bool askRedraw = false; if (m_tiledTexture) askRedraw = m_tiledTexture->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(); + return askRedraw; } void PaintedSurface::markAsDirty(const SkRegion& dirtyArea) { - m_tiledTexture->markAsDirty(dirtyArea); -} - -bool PaintedSurface::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) -{ - m_layerLock.lock(); - LayerAndroid* layer = m_layer; - SkSafeRef(layer); - m_layerLock.unlock(); - - if (!layer) - return false; - - layer->contentDraw(canvas); - m_pictureUsed = layer->pictureUsed(); - *pictureUsed = m_pictureUsed; - SkSafeUnref(layer); - - return true; + m_updateManager.updateInval(dirtyArea); } void PaintedSurface::paintExtra(SkCanvas* canvas) diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h index 88a9303..cda5960 100644 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.h +++ b/Source/WebCore/platform/graphics/android/PaintedSurface.h @@ -36,20 +36,22 @@ #include "TilesManager.h" #include "TilePainter.h" #include "TransformationMatrix.h" +#include "UpdateManager.h" class SkCanvas; class SkRegion; namespace WebCore { -class PaintedSurface : public SkRefCnt, TilePainter { +class UpdateManager; + +class PaintedSurface : public SkRefCnt { public: PaintedSurface(LayerAndroid* layer) : m_layer(layer) , m_tiledTexture(0) , m_scale(0) , m_pictureUsed(0) - , m_busy(false) { TilesManager::instance()->addPaintedSurface(this); SkSafeRef(m_layer); @@ -70,18 +72,14 @@ public: void removeLayer(); void removeLayer(LayerAndroid* layer); void replaceLayer(LayerAndroid* layer); - bool busy(); bool owns(BaseTileTexture* texture); void computeVisibleArea(); - // TilePainter methods - virtual bool paint(BaseTile*, SkCanvas*, unsigned int*); + // TilePainter methods for TiledTexture virtual void paintExtra(SkCanvas*); virtual const TransformationMatrix* transform(); - virtual void beginPaint(); - virtual void endPaint(); // used by TiledTexture const IntRect& area() { return m_area; } @@ -92,6 +90,8 @@ public: TiledTexture* texture() { return m_tiledTexture; } private: + UpdateManager m_updateManager; + LayerAndroid* m_layer; TiledTexture* m_tiledTexture; @@ -101,8 +101,6 @@ private: unsigned int m_pictureUsed; - bool m_busy; - android::Mutex m_layerLock; }; diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index 31034e3..191edf3 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -40,8 +40,6 @@ 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 780a604..718908d 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.h +++ b/Source/WebCore/platform/graphics/android/TiledPage.h @@ -84,8 +84,6 @@ 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 c1fb4d1..8c63b42 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -33,12 +33,15 @@ #include "PaintTileOperation.h" #include "SkCanvas.h" -#ifdef DEBUG - #include <cutils/log.h> #include <wtf/CurrentTime.h> #include <wtf/text/CString.h> +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__) + +#ifdef DEBUG + #undef XLOG #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__) @@ -51,7 +54,7 @@ namespace WebCore { -void TiledTexture::prepare(GLWebViewState* state, bool repaint) +void TiledTexture::prepare(GLWebViewState* state, bool repaint, bool startFastSwap) { if (!m_surface) return; @@ -66,13 +69,6 @@ void TiledTexture::prepare(GLWebViewState* state, bool repaint) ceilf(visibleArea.width() * m_surface->scale()), ceilf(visibleArea.height() * m_surface->scale())); - for (unsigned int i = 0; i < m_tiles.size(); i++) { - BaseTile* tile = m_tiles[i]; - if (!m_dirtyRegion.isEmpty()) - tile->markAsDirty(1, m_dirtyRegion); - } - m_dirtyRegion.setEmpty(); - if (area.width() == 0 && area.height() == 0) { m_area.setWidth(0); m_area.setHeight(0); @@ -89,7 +85,7 @@ void TiledTexture::prepare(GLWebViewState* state, bool repaint) m_area.setWidth(ceilf(right) - m_area.x()); m_area.setHeight(ceilf(bottom) - m_area.y()); - XLOG("for TiledTexture %x, we have a visible area of %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", + XLOG("for TiledTexture %p, we have a visible area of %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", this, visibleArea.x(), visibleArea.y(), visibleArea.width(), visibleArea.height(), @@ -104,6 +100,47 @@ void TiledTexture::prepare(GLWebViewState* state, bool repaint) m_prevScale = m_surface->scale(); + // unlock if tiles all ready + bool tilesAllReady = true; + for (unsigned int i = 0; i < m_tiles.size(); i++) { + BaseTile* tile = m_tiles[i]; + if (tile->isTileVisible(m_area) && !tile->isTileReady()) { + tilesAllReady = false; + break; + } + } + + // startFastSwap=true will swap all ready tiles each + // frame until all visible tiles are up to date + if (tilesAllReady) + m_swapWhateverIsReady = false; + else if (startFastSwap) + m_swapWhateverIsReady = true; + + // swap as appropriate + for (unsigned int i = 0; i < m_tiles.size(); i++) { + BaseTile* tile = m_tiles[i]; + if (tilesAllReady || m_swapWhateverIsReady) + tile->swapTexturesIfNeeded(); + } + + if (tilesAllReady) { + m_updateManager.swap(); + m_dirtyRegion.op(m_updateManager.getPaintingInval(), SkRegion::kUnion_Op); + XLOG("TT %p swapping, now painting with picture %p" + this, m_updateManager.getPaintingPicture()); + m_updateManager.clearPaintingInval(); + } + + // apply dirty region to affected tiles + if (!m_dirtyRegion.isEmpty()) { + for (unsigned int i = 0; i < m_tiles.size(); i++) { + // TODO: don't mark all tiles dirty + m_tiles[i]->markAsDirty(1, m_dirtyRegion); + } + } + m_dirtyRegion.setEmpty(); + for (int i = 0; i < m_area.width(); i++) { if (goingDown) { for (int j = 0; j < m_area.height(); j++) { @@ -117,9 +154,14 @@ void TiledTexture::prepare(GLWebViewState* state, bool repaint) } } -void TiledTexture::markAsDirty(const SkRegion& dirtyArea) +void TiledTexture::update(const SkRegion& invalRegion, SkPicture* picture) { - m_dirtyRegion.op(dirtyArea, SkRegion::kUnion_Op); + XLOG("TT %p, update manager %p updated with picture %p, region empty %d", + this, &m_updateManager, picture, invalRegion.isEmpty()); + // attempt to update inval and picture. these may be deferred below instead + // of used immediately. + m_updateManager.updateInval(invalRegion); + m_updateManager.updatePicture(picture); } void TiledTexture::prepareTile(bool repaint, int x, int y) @@ -130,6 +172,7 @@ void TiledTexture::prepareTile(bool repaint, int x, int y) m_tiles.append(tile); } + XLOG("preparing tile %p, painter is this %p", tile, this); tile->setContents(this, x, y, m_surface->scale()); // TODO: move below (which is largely the same for layers / tiled page) into @@ -160,9 +203,8 @@ bool TiledTexture::draw() TilesManager::instance()->getTilesTracker()->trackLayer(); #endif - bool askRedraw = false; if (m_area.width() == 0 || m_area.height() == 0) - return askRedraw; + return false; #ifdef DEBUG TilesManager::instance()->getTilesTracker()->trackVisibleLayer(); @@ -172,38 +214,35 @@ bool TiledTexture::draw() const float tileWidth = TilesManager::layerTileWidth() * m_invScale; const float tileHeight = TilesManager::layerTileHeight() * m_invScale; XLOG("draw tile %x, tiles %d", this, m_tiles.size()); - for (unsigned int i = 0; i <m_tiles.size(); i++) { + + bool askRedraw = false; + for (unsigned int i = 0; i < m_tiles.size(); i++) { BaseTile* tile = m_tiles[i]; - if (tile->x() >= m_area.x() - && tile->x() < m_area.x() + m_area.width() - && tile->y() >= m_area.y() - && tile->y() < m_area.y() + m_area.height()) { + + askRedraw |= !tile->isTileReady(); + if (tile->isTileVisible(m_area)) { SkRect rect; rect.fLeft = tile->x() * tileWidth; rect.fTop = tile->y() * tileHeight; rect.fRight = rect.fLeft + tileWidth; rect.fBottom = rect.fTop + tileHeight; XLOG(" - [%d], { painter %x vs %x }, tile %x %d,%d at scale %.2f [ready: %d] dirty: %d", - i, this, tile->painter(), tile, tile->x(), tile->y(), tile->scale(), tile->isTileReady(), tile->isDirty()); - askRedraw |= !tile->isTileReady(); - tile->swapTexturesIfNeeded(); + i, this, tile->painter(), tile, tile->x(), tile->y(), + tile->scale(), tile->isTileReady(), tile->isDirty()); tile->draw(m_surface->opacity(), rect, m_surface->scale()); #ifdef DEBUG TilesManager::instance()->getTilesTracker()->track(tile->isTileReady(), tile->backTexture()); #endif } } + + // need to redraw if some visible tile wasn't ready return askRedraw; } bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) { - if (!m_surface) - return false; - - XLOG("painting scheduled tile(%x : %d, %d, %.2f, %x) for %x", - tile, tile->x(), tile->y(), tile->scale(), tile->painter(), this); - return m_surface->paint(tile, canvas, pictureUsed); + return m_updateManager.paint(tile, canvas, pictureUsed); } void TiledTexture::paintExtra(SkCanvas* canvas) @@ -216,18 +255,6 @@ 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() { for (unsigned int i = 0; i < m_tiles.size(); i++) { diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h index 6ebfc05..aa82e36 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.h +++ b/Source/WebCore/platform/graphics/android/TiledTexture.h @@ -34,11 +34,13 @@ #include "SkRegion.h" #include "TextureOwner.h" #include "TilePainter.h" +#include "UpdateManager.h" class SkCanvas; namespace WebCore { +class UpdateManager; class PaintedSurface; class TiledTexture : public TilePainter { @@ -48,6 +50,7 @@ public: , m_prevTileX(0) , m_prevTileY(0) , m_prevScale(1) + , m_swapWhateverIsReady(false) { m_dirtyRegion.setEmpty(); #ifdef DEBUG_COUNT @@ -62,11 +65,11 @@ public: removeTiles(); }; - void prepare(GLWebViewState* state, bool repaint); + void prepare(GLWebViewState* state, bool repaint, bool startFastSwap); bool draw(); void prepareTile(bool repaint, int x, int y); - void markAsDirty(const SkRegion& dirtyArea); + void update(const SkRegion& dirtyArea, SkPicture* picture); BaseTile* getTile(int x, int y); @@ -77,19 +80,25 @@ public: bool paint(BaseTile* tile, SkCanvas*, unsigned int*); virtual void paintExtra(SkCanvas*); virtual const TransformationMatrix* transform(); - virtual void beginPaint(); - virtual void endPaint(); private: + bool tileIsVisible(BaseTile* tile); + + UpdateManager m_updateManager; + PaintedSurface* m_surface; Vector<BaseTile*> m_tiles; + // tile coordinates in viewport, set in prepare() IntRect m_area; + SkRegion m_dirtyRegion; int m_prevTileX; int m_prevTileY; float m_prevScale; + + bool m_swapWhateverIsReady; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/UpdateManager.cpp b/Source/WebCore/platform/graphics/android/UpdateManager.cpp new file mode 100644 index 0000000..1c20f1f --- /dev/null +++ b/Source/WebCore/platform/graphics/android/UpdateManager.cpp @@ -0,0 +1,120 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PaintedSurface.h" + +#include "LayerAndroid.h" +#include "TilesManager.h" +#include "SkCanvas.h" +#include "SkPicture.h" + +#include <cutils/log.h> +#include <wtf/CurrentTime.h> +#include <wtf/text/CString.h> + +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "UpdateManager", __VA_ARGS__) + +#ifdef DEBUG + +#undef XLOG +#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "UpdateManager", __VA_ARGS__) + +#else + +#undef XLOG +#define XLOG(...) + +#endif // DEBUG + +namespace WebCore { + +UpdateManager::UpdateManager() + : m_paintingPicture(0) + , m_deferredPicture(0) +{ +} + +UpdateManager::~UpdateManager() +{ + SkSafeUnref(m_paintingPicture); + SkSafeUnref(m_deferredPicture); +} + +void UpdateManager::swap() +{ + m_paintingInval.op(m_deferredInval, SkRegion::kUnion_Op); + m_deferredInval.setEmpty(); + + android::Mutex::Autolock lock(m_paintingPictureSync); + if (m_deferredPicture) { + XLOG("unlock of updatemanager %p, was painting %p, now painting %p", + this, m_paintingPicture, m_deferredPicture); + SkSafeUnref(m_paintingPicture); + m_paintingPicture = m_deferredPicture; + m_deferredPicture = 0; + } +} + +void UpdateManager::updateInval(const SkRegion& invalRegion) +{ + m_deferredInval.op(invalRegion, SkRegion::kUnion_Op); +} + +void UpdateManager::updatePicture(SkPicture* picture) +{ + SkSafeRef(picture); + SkSafeUnref(m_deferredPicture); + m_deferredPicture = picture; +} + +bool UpdateManager::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) +{ + m_paintingPictureSync.lock(); + SkPicture* picture = m_paintingPicture; + SkSafeRef(picture); + m_paintingPictureSync.unlock(); + + XLOG("UpdateManager %p painting with picture %p", this, picture); + + if (!picture) + return false; + + canvas->drawPicture(*picture); + + // TODO: visualization layer diagonals + + SkSafeUnref(picture); + return true; +} + + +void UpdateManager::clearPaintingInval() +{ + m_paintingInval.setEmpty(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/UpdateManager.h b/Source/WebCore/platform/graphics/android/UpdateManager.h new file mode 100644 index 0000000..6254184 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/UpdateManager.h @@ -0,0 +1,87 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UpdateManager_h +#define UpdateManager_h + +class SkCanvas; +class SkRegion; + +namespace WebCore { + +class BaseTile; + +// UpdateManager Architecture + +// The UpdateManager is used to defer updates and invalidations to a layer, +// so that the layer can finish painting one version completely without being +// interrupted by new invals/content + +class UpdateManager { +public: + UpdateManager(); + + ~UpdateManager(); + + // swap deferred members in place of painting members + void swap(); + + void updateInval(const SkRegion& invalRegion); + + void updatePicture(SkPicture* picture); + + bool paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed); + + void clearPaintingInval(); + + const SkRegion& getPaintingInval() { + return m_paintingInval; + } + + SkPicture* getPaintingPicture() { + // NOTE: only modified on UI thread, so UI thread access doesn't need mutex + return m_paintingPicture; + } + +private: + // protect m_paintingPicture + // swap() on UI thread modifies + // paint() on texture gen thread reads + android::Mutex m_paintingPictureSync; + SkPicture* m_paintingPicture; + + // inval region to be redrawn with the current paintingPicture + SkRegion m_paintingInval; + + // most recently received picture, moved into painting on swap() + SkPicture* m_deferredPicture; + + // all invals since last swap(), merged with painting inval on swap() + SkRegion m_deferredInval; +}; + +} // namespace WebCore + +#endif //#define UpdateManager_h |