X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=Source%2FWebCore%2Fplatform%2Fgraphics%2Fandroid%2FTiledTexture.cpp;h=91d689701585c70af1aca0f9b1a84f11b67abf83;hb=60082004bd7975748f8b0bee91645de245f1ea94;hp=b2523039e29f74daea438938726a58925b0c8255;hpb=4476ae7e9e02e5c2ff8a776f01d3fb50e8a4c895;p=android-x86%2Fexternal-webkit.git diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index b2523039e..91d689701 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -32,6 +32,7 @@ #include "PaintedSurface.h" #include "PaintTileOperation.h" #include "SkCanvas.h" +#include "SkPicture.h" #include #include @@ -54,58 +55,91 @@ namespace WebCore { -bool TiledTexture::ready() { +TiledTexture::~TiledTexture() +{ + SkSafeUnref(m_paintingPicture); +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("TiledTexture"); +#endif + removeTiles(); +} + +bool TiledTexture::ready() +{ bool tilesAllReady = true; bool tilesVisible = false; 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; - } - if (tile->isTileVisible(m_area)) + if (tile->isTileVisible(m_area)) { tilesVisible = true; + if (!tile->isTileReady()) { + tilesAllReady = false; + break; + } + } } // For now, if no textures are available, consider ourselves as ready // in order to unblock the zooming process. // FIXME: have a better system -- maybe keeping the last scale factor // able to fully render everything + XLOG("TT %p, ready %d, visible %d, texturesRemain %d", + this, tilesAllReady, tilesVisible, + TilesManager::instance()->layerTexturesRemain()); + return !TilesManager::instance()->layerTexturesRemain() || !tilesVisible || tilesAllReady; } -void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, - bool startFastSwap, IntRect& visibleArea) +void TiledTexture::swapTiles() { - if (!m_surface) - return; - - if (!m_surface->layer()) - return; + int swaps = 0; + for (unsigned int i = 0; i < m_tiles.size(); i++) + if (m_tiles[i]->swapTexturesIfNeeded()) + swaps++; + XLOG("TT %p swapping, swaps = %d", this, swaps); +} - // first, how many tiles do we need +IntRect TiledTexture::computeTilesArea(IntRect& visibleArea, float scale) +{ + IntRect computedArea; IntRect area(visibleArea.x() * scale, visibleArea.y() * scale, ceilf(visibleArea.width() * scale), ceilf(visibleArea.height() * scale)); + XLOG("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height()); + if (area.width() == 0 && area.height() == 0) { - m_area.setWidth(0); - m_area.setHeight(0); - return; + computedArea.setWidth(0); + computedArea.setHeight(0); + return computedArea; } int tileWidth = TilesManager::instance()->layerTileWidth(); int tileHeight = TilesManager::instance()->layerTileHeight(); - m_area.setX(area.x() / tileWidth); - m_area.setY(area.y() / tileHeight); + computedArea.setX(area.x() / tileWidth); + computedArea.setY(area.y() / tileHeight); float right = (area.x() + area.width()) / (float) tileWidth; float bottom = (area.y() + area.height()) / (float) tileHeight; - m_area.setWidth(ceilf(right) - m_area.x()); - m_area.setHeight(ceilf(bottom) - m_area.y()); + computedArea.setWidth(ceilf(right) - computedArea.x()); + computedArea.setHeight(ceilf(bottom) - computedArea.y()); + return computedArea; +} + +void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, + bool startFastSwap, IntRect& visibleArea) +{ + if (!m_surface) + return; - XLOG("for TiledTexture %p, we prepare with scale %.2f, have a visible area of %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", + // first, how many tiles do we need + m_area = computeTilesArea(visibleArea, scale); + if (m_area.isEmpty()) + return; + + XLOG("for TiledTexture %p, we prepare with scale %.2f, have a visible area of " + " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", this, scale, visibleArea.x(), visibleArea.y(), visibleArea.width(), visibleArea.height(), @@ -120,31 +154,6 @@ void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, m_scale = scale; - // unlock if tiles all ready - bool tilesAllReady = ready(); - - // 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++) { @@ -169,12 +178,14 @@ void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, void TiledTexture::update(const SkRegion& invalRegion, SkPicture* picture) { - 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); + XLOG("TT %p update, current region empty %d, new empty %d, painting picture %p", + this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty(), picture); + m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); + + android::Mutex::Autolock lock(m_paintingPictureSync); + SkSafeRef(picture); + SkSafeUnref(m_paintingPicture); + m_paintingPicture = picture; } void TiledTexture::prepareTile(bool repaint, int x, int y) @@ -185,7 +196,7 @@ void TiledTexture::prepareTile(bool repaint, int x, int y) m_tiles.append(tile); } - XLOG("preparing tile %p, painter is this %p", tile, this); + XLOG("preparing tile %p at %d, %d, painter is this %p", tile, x, y, this); tile->setContents(this, x, y, m_scale); // TODO: move below (which is largely the same for layers / tiled page) into @@ -193,8 +204,8 @@ void TiledTexture::prepareTile(bool repaint, int x, int y) if (tile->isDirty() || !tile->frontTexture()) tile->reserveTexture(); - LayerAndroid* layer = m_surface->layer(); - if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && layer) { + bool hasPicture = m_paintingPicture != 0; // safely read on UI thread, since only UI thread writes + if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && hasPicture) { PaintTileOperation *operation = new PaintTileOperation(tile, m_surface); TilesManager::instance()->scheduleOperation(operation); } @@ -210,8 +221,16 @@ BaseTile* TiledTexture::getTile(int x, int y) return 0; } +int TiledTexture::nbTextures(IntRect& area, float scale) +{ + IntRect computedTilesArea = computeTilesArea(area, scale); + return computedTilesArea.width() * computedTilesArea.height(); +} + bool TiledTexture::draw() { + XLOG("TT %p draw", this); + #ifdef DEBUG TilesManager::instance()->getTilesTracker()->trackLayer(); #endif @@ -238,7 +257,7 @@ bool TiledTexture::draw() 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 vs %.2f [ready: %d] dirty: %d", + XLOG("- [%d], { painter %x vs %x }, tile %x %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d", i, this, tile->painter(), tile, tile->x(), tile->y(), tile->scale(), m_scale, tile->isTileReady(), tile->isDirty()); tile->draw(m_surface->opacity(), rect, m_scale); @@ -254,7 +273,23 @@ bool TiledTexture::draw() bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) { - return m_updateManager.paint(tile, canvas, pictureUsed); + m_paintingPictureSync.lock(); + SkPicture* picture = m_paintingPicture; + SkSafeRef(picture); + m_paintingPictureSync.unlock(); + + if (!picture) { + XLOG("TT %p COULDNT PAINT, NO PICTURE", this); + return false; + } + + XLOG("TT %p painting with picture %p", this, picture); + + canvas->drawPicture(*picture); + + SkSafeUnref(picture); + + return true; } const TransformationMatrix* TiledTexture::transform() @@ -319,8 +354,8 @@ void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, m_zooming = true; } - XLOG("\n*** %x Drawing with scale %.2f, futureScale: %.2f, zooming: %d", - this, scale, m_futureScale, m_zooming); + XLOG("Preparing DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d", + this, scale, m_scale, m_futureScale, m_zooming); if (m_scale > 0) m_frontTexture->prepare(state, m_scale, repaint, startFastSwap, m_preZoomVisibleArea); @@ -329,6 +364,7 @@ void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) { m_backTexture->prepare(state, m_futureScale, repaint, startFastSwap, visibleArea); if (m_backTexture->ready()) { + m_backTexture->swapTiles(); swap(); m_zooming = false; } @@ -357,6 +393,12 @@ void DualTiledTexture::update(const SkRegion& dirtyArea, SkPicture* picture) m_frontTexture->update(dirtyArea, picture); } +void DualTiledTexture::swapTiles() +{ + m_backTexture->swapTiles(); + m_frontTexture->swapTiles(); +} + bool DualTiledTexture::owns(BaseTileTexture* texture) { bool owns = m_textureA->owns(texture);