diff options
Diffstat (limited to 'WebCore')
-rw-r--r-- | WebCore/Android.mk | 2 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseLayerAndroid.cpp | 14 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseTile.cpp | 20 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseTile.h | 5 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.cpp | 2 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/PaintTileOperation.cpp (renamed from WebCore/platform/graphics/android/TileSet.cpp) | 86 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/PaintTileOperation.h (renamed from WebCore/platform/graphics/android/PaintTileSetOperation.h) | 30 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/QueuedOperation.h | 17 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TexturesGenerator.cpp | 102 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TexturesGenerator.h | 6 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TileSet.h | 77 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TiledPage.cpp | 135 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TiledPage.h | 11 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TilesManager.h | 11 |
14 files changed, 241 insertions, 277 deletions
diff --git a/WebCore/Android.mk b/WebCore/Android.mk index feeb56b..5bc6d83 100644 --- a/WebCore/Android.mk +++ b/WebCore/Android.mk @@ -620,6 +620,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/MediaLayer.cpp \ platform/graphics/android/MediaTexture.cpp \ platform/graphics/android/PaintLayerOperation.cpp \ + platform/graphics/android/PaintTileOperation.cpp \ platform/graphics/android/PathAndroid.cpp \ platform/graphics/android/PatternAndroid.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ @@ -630,7 +631,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/TexturesGenerator.cpp \ platform/graphics/android/TilesManager.cpp \ platform/graphics/android/TiledPage.cpp \ - platform/graphics/android/TileSet.cpp \ platform/graphics/android/VideoLayerAndroid.cpp \ platform/graphics/android/android_graphics.cpp \ diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index c59a5a5..c61a09a 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -163,13 +163,19 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double zooming = true; } + // Display the current page + TiledPage* tiledPage = m_glWebViewState->frontPage(); + tiledPage->setScale(m_glWebViewState->currentScale()); + // Let's prepare the page if needed if (prepareNextTiledPage) { TiledPage* nextTiledPage = m_glWebViewState->backPage(); nextTiledPage->setScale(scale); m_glWebViewState->setFutureViewport(viewportTileBounds); m_glWebViewState->lockBaseLayerUpdate(); - nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds, true); + nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds); + // Cancel pending paints for the foreground page + TilesManager::instance()->removePaintOperationsForPage(tiledPage, false); } float transparency = 1; @@ -205,9 +211,6 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double } } - // Display the current page - TiledPage* tiledPage = m_glWebViewState->frontPage(); - tiledPage->setScale(m_glWebViewState->currentScale()); const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds(); TiledPage* nextTiledPage = m_glWebViewState->backPage(); @@ -240,7 +243,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double if (!zooming) m_glWebViewState->unlockBaseLayerUpdate(); - tiledPage->prepare(goingDown, goingLeft, preZoomBounds, true); + if (!prepareNextTiledPage) + tiledPage->prepare(goingDown, goingLeft, preZoomBounds); tiledPage->draw(transparency, preZoomBounds); } diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp index 25ba60f..c74a278 100644 --- a/WebCore/platform/graphics/android/BaseTile.cpp +++ b/WebCore/platform/graphics/android/BaseTile.cpp @@ -66,6 +66,7 @@ BaseTile::BaseTile() , m_texture(0) , m_scale(1) , m_dirty(true) + , m_repaintPending(false) , m_usable(true) , m_lastDirtyPicture(0) , m_fullRepaintA(true) @@ -162,12 +163,31 @@ bool BaseTile::isDirty() return m_dirty; } +bool BaseTile::isRepaintPending() +{ + android::AutoMutex lock(m_atomicSync); + return m_repaintPending; +} + +void BaseTile::setRepaintPending(bool pending) +{ + android::AutoMutex lock(m_atomicSync); + m_repaintPending = pending; +} + void BaseTile::setUsedLevel(int usedLevel) { if (m_texture) m_texture->setUsedLevel(usedLevel); } +int BaseTile::usedLevel() +{ + if (m_texture) + return m_texture->usedLevel(); + return -1; +} + void BaseTile::draw(float transparency, SkRect& rect, float scale) { if (m_x < 0 || m_y < 0 || m_scale != scale) diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h index 63ce117..7b28f76 100644 --- a/WebCore/platform/graphics/android/BaseTile.h +++ b/WebCore/platform/graphics/android/BaseTile.h @@ -72,6 +72,7 @@ public: void reserveTexture(); void setUsedLevel(int); + int usedLevel(); bool isTileReady(); void draw(float transparency, SkRect& rect, float scale); @@ -89,6 +90,8 @@ public: void markAsDirty(const unsigned int pictureCount, const SkRegion& dirtyArea); bool isDirty(); + bool isRepaintPending(); + void setRepaintPending(bool pending); void setUsable(bool usable); float scale() const { return m_scale; } void setScale(float scale); @@ -114,6 +117,8 @@ private: float m_scale; // used to signal that the that the tile is out-of-date and needs to be redrawn bool m_dirty; + // used to signal that a repaint is pending + bool m_repaintPending; // used to signal whether or not the draw can use this tile. bool m_usable; // stores the id of the latest picture from webkit that caused this tile to diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index 78e55c1..53edb45 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -889,7 +889,7 @@ void LayerAndroid::createGLTextures() uniqueId(), this, m_dirty, m_reservedTexture, m_reservedTexture->rect().width(), m_reservedTexture->rect().height()); PaintLayerOperation* operation = new PaintLayerOperation(this); - TilesManager::instance()->scheduleOperation(operation, !m_drawingTexture); + TilesManager::instance()->scheduleOperation(operation); } else { XLOG("We don't schedule a paint for layer %d (%x), because we already sent a request", uniqueId(), this); diff --git a/WebCore/platform/graphics/android/TileSet.cpp b/WebCore/platform/graphics/android/PaintTileOperation.cpp index 1214aa2..222b69b 100644 --- a/WebCore/platform/graphics/android/TileSet.cpp +++ b/WebCore/platform/graphics/android/PaintTileOperation.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2010, The Android Open Source Project + * 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 @@ -24,64 +24,58 @@ */ #include "config.h" -#include "TileSet.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "ClassTracker.h" -#include "TilesManager.h" - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TileSet", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG +#include "PaintTileOperation.h" namespace WebCore { -TileSet::TileSet(TiledPage* tiledPage, int rows, int cols) - : m_tiledPage(tiledPage) - , m_nbRows(rows) - , m_nbCols(cols) +PaintTileOperation::PaintTileOperation(BaseTile* tile) + : QueuedOperation(QueuedOperation::PaintTile, tile->page()) + , m_tile(tile) { -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("TileSet"); -#endif + if (m_tile) + m_tile->setRepaintPending(true); } -TileSet::~TileSet() +PaintTileOperation::~PaintTileOperation() { -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("TileSet"); -#endif + if (m_tile) { + m_tile->setRepaintPending(false); + m_tile = 0; + } } -bool TileSet::operator==(const TileSet& set) +bool PaintTileOperation::operator==(const QueuedOperation* operation) { - return m_tiledPage == set.m_tiledPage - && m_nbRows == set.m_nbRows - && m_nbCols == set.m_nbCols; + if (operation->type() != type()) + return false; + const PaintTileOperation* op = static_cast<const PaintTileOperation*>(operation); + return op->m_tile == m_tile; } - -void TileSet::paint() +void PaintTileOperation::run() { - XLOG("%x, painting %d tiles", this, m_tiles.size()); - for (unsigned int i = 0; i < m_tiles.size(); i++) - m_tiles[i]->paintBitmap(); - XLOG("%x, end of painting %d tiles", this, m_tiles.size()); + if (m_tile) { + m_tile->paintBitmap(); + m_tile->setRepaintPending(false); + m_tile = 0; + } } -} // namespace WebCore +int PaintTileOperation::priority() +{ + if (!m_tile || m_tile->usedLevel() < 0) + return -1; + bool goingDown = m_tile->page()->scrollingDown(); + SkIRect *rect = m_tile->page()->expandedTileBounds(); + int firstTileX = rect->fLeft; + int nbTilesWidth = rect->width(); + int priority = m_tile->x() - firstTileX; + if (goingDown) + priority += (rect->fBottom - m_tile->y()) * nbTilesWidth; + else + priority += (m_tile->y() - rect->fTop) * nbTilesWidth; + priority += m_tile->usedLevel() * 100000; + return priority; +} -#endif // USE(ACCELERATED_COMPOSITING) +} diff --git a/WebCore/platform/graphics/android/PaintTileSetOperation.h b/WebCore/platform/graphics/android/PaintTileOperation.h index fba7220..0920f32 100644 --- a/WebCore/platform/graphics/android/PaintTileSetOperation.h +++ b/WebCore/platform/graphics/android/PaintTileOperation.h @@ -27,33 +27,19 @@ #define PaintTileSetOperation_h #include "QueuedOperation.h" -#include "TileSet.h" namespace WebCore { -class PaintTileSetOperation : public QueuedOperation { +class PaintTileOperation : public QueuedOperation { public: - PaintTileSetOperation(TileSet* set) - : QueuedOperation(QueuedOperation::PaintTileSet, set->page()) - , m_set(set) {} - virtual ~PaintTileSetOperation() - { - delete m_set; - } - virtual bool operator==(const QueuedOperation* operation) - { - if (operation->type() != type()) - return false; - const PaintTileSetOperation* op = static_cast<const PaintTileSetOperation*>(operation); - return op->m_set == m_set; - } - virtual void run() - { - if (m_set) - m_set->paint(); - } + PaintTileOperation(BaseTile* tile); + virtual ~PaintTileOperation(); + virtual bool operator==(const QueuedOperation* operation); + virtual void run(); + virtual int priority(); + private: - TileSet* m_set; + BaseTile* m_tile; }; } diff --git a/WebCore/platform/graphics/android/QueuedOperation.h b/WebCore/platform/graphics/android/QueuedOperation.h index 089483d..98f3e2f 100644 --- a/WebCore/platform/graphics/android/QueuedOperation.h +++ b/WebCore/platform/graphics/android/QueuedOperation.h @@ -32,13 +32,14 @@ namespace WebCore { class QueuedOperation { public: - enum OperationType { Undefined, PaintTileSet, PaintLayer, DeleteTexture }; + enum OperationType { Undefined, PaintTile, PaintLayer, DeleteTexture }; QueuedOperation(OperationType type, TiledPage* page) : m_type(type) , m_page(page) {} virtual ~QueuedOperation() {} virtual void run() = 0; virtual bool operator==(const QueuedOperation* operation) = 0; + virtual int priority() { return -1; } OperationType type() const { return m_type; } TiledPage* page() const { return m_page; } private: @@ -65,6 +66,20 @@ class PageFilter : public OperationFilter { TiledPage* m_page; }; +class PagePaintFilter : public OperationFilter { + public: + PagePaintFilter(TiledPage* page) : m_page(page) {} + virtual bool check(QueuedOperation* operation) + { + if (operation->type() == QueuedOperation::PaintTile + && operation->page() == m_page) + return true; + return false; + } + private: + TiledPage* m_page; +}; + } #endif // QueuedOperation_h diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp index ad5de1f..e6bef6a 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.cpp +++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp @@ -51,27 +51,11 @@ namespace WebCore { -void TexturesGenerator::scheduleOperation(QueuedOperation* operation, bool scheduleFirst) +void TexturesGenerator::scheduleOperation(QueuedOperation* operation) { { android::Mutex::Autolock lock(mRequestedOperationsLock); - for (unsigned int i = 0; i < mRequestedOperations.size(); i++) { - QueuedOperation** s = &mRequestedOperations[i]; - // A similar operation is already in the queue. The newer operation may - // have additional dirty tiles so delete the existing operation and - // replace it with the new one. - if (*s && *s == operation) { - QueuedOperation* oldOperation = *s; - *s = operation; - delete oldOperation; - return; - } - } - - if (scheduleFirst) - mRequestedOperations.prepend(operation); - else - mRequestedOperations.append(operation); + mRequestedOperations.append(operation); } mRequestedOperationsCond.signal(); } @@ -81,6 +65,11 @@ void TexturesGenerator::removeOperationsForPage(TiledPage* page) removeOperationsForFilter(new PageFilter(page)); } +void TexturesGenerator::removePaintOperationsForPage(TiledPage* page, bool waitForRunning) +{ + removeOperationsForFilter(new PagePaintFilter(page), waitForRunning); +} + void TexturesGenerator::removeOperationsForBaseLayer(BaseLayerAndroid* layer) { removeOperationsForFilter(new PaintLayerBaseFilter(layer)); @@ -93,6 +82,11 @@ void TexturesGenerator::removeOperationsForTexture(LayerTexture* texture) void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter) { + removeOperationsForFilter(filter, true); +} + +void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning) +{ android::Mutex::Autolock lock(mRequestedOperationsLock); for (unsigned int i = 0; i < mRequestedOperations.size();) { QueuedOperation* operation = mRequestedOperations[i]; @@ -104,18 +98,22 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter) } } - QueuedOperation* operation = m_currentOperation; - if (operation && filter->check(operation)) - m_waitForCompletion = true; - - delete filter; - - // At this point, it means that we are currently executing an operation that - // we want to be removed -- we should wait until it is done, so that - // when we return our caller can be sure that there is no more operations - // in the queue matching the given filter. - while (m_waitForCompletion) - mRequestedOperationsCond.wait(mRequestedOperationsLock); + if (waitForRunning) { + QueuedOperation* operation = m_currentOperation; + if (operation && filter->check(operation)) + m_waitForCompletion = true; + + delete filter; + + // At this point, it means that we are currently executing an operation that + // we want to be removed -- we should wait until it is done, so that + // when we return our caller can be sure that there is no more operations + // in the queue matching the given filter. + while (m_waitForCompletion) + mRequestedOperationsCond.wait(mRequestedOperationsLock); + } else { + delete filter; + } } status_t TexturesGenerator::readyToRun() @@ -125,6 +123,37 @@ status_t TexturesGenerator::readyToRun() return NO_ERROR; } +// Must be called from within a lock! +QueuedOperation* TexturesGenerator::popNext() +{ + // Priority can change between when it was added and now + // Hence why the entire queue is rescanned + QueuedOperation* current = mRequestedOperations.last(); + int currentPriority = current->priority(); + if (currentPriority < 0) { + mRequestedOperations.removeLast(); + return current; + } + int currentIndex = mRequestedOperations.size() - 1; + // Scan from the back to make removing faster (less items to copy) + for (int i = mRequestedOperations.size() - 2; i >= 0; i--) { + QueuedOperation *next = mRequestedOperations[i]; + int nextPriority = next->priority(); + if (nextPriority < 0) { + // Found a very high priority item, go ahead and just handle it now + mRequestedOperations.remove(i); + return next; + } + if (nextPriority < currentPriority) { + current = next; + currentPriority = nextPriority; + currentIndex = i; + } + } + mRequestedOperations.remove(currentIndex); + return current; +} + bool TexturesGenerator::threadLoop() { // Check if we have any pending operations. @@ -138,20 +167,14 @@ bool TexturesGenerator::threadLoop() m_currentOperation = 0; bool stop = false; while (!stop) { - XLOG("threadLoop evaluating the requests"); mRequestedOperationsLock.lock(); - if (mRequestedOperations.size()) { - m_currentOperation = mRequestedOperations.first(); - mRequestedOperations.remove(0); - XLOG("threadLoop, popping the first request (%d requests left)", - mRequestedOperations.size()); - } + if (mRequestedOperations.size()) + m_currentOperation = popNext(); mRequestedOperationsLock.unlock(); if (m_currentOperation) { - XLOG("threadLoop, painting the request"); + XLOG("threadLoop, painting the request with priority %d", m_currentOperation->priority()); m_currentOperation->run(); - XLOG("threadLoop, painting the request - DONE"); } mRequestedOperationsLock.lock(); @@ -168,6 +191,7 @@ bool TexturesGenerator::threadLoop() mRequestedOperationsLock.unlock(); } + XLOG("threadLoop empty"); return true; } diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h index 169471c..b03f52d 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.h +++ b/WebCore/platform/graphics/android/TexturesGenerator.h @@ -30,7 +30,6 @@ #include "LayerTexture.h" #include "QueuedOperation.h" -#include "TileSet.h" #include "TiledPage.h" #include <utils/threads.h> @@ -52,11 +51,14 @@ public: void removeOperationsForPage(TiledPage* page); void removeOperationsForBaseLayer(BaseLayerAndroid* layer); void removeOperationsForTexture(LayerTexture* texture); + void removePaintOperationsForPage(TiledPage* page, bool waitForRunning); void removeOperationsForFilter(OperationFilter* filter); + void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning); - void scheduleOperation(QueuedOperation* operation, bool scheduleFirst); + void scheduleOperation(QueuedOperation* operation); private: + QueuedOperation* popNext(); virtual bool threadLoop(); Vector<QueuedOperation*> mRequestedOperations; android::Mutex mRequestedOperationsLock; diff --git a/WebCore/platform/graphics/android/TileSet.h b/WebCore/platform/graphics/android/TileSet.h deleted file mode 100644 index aa0f2ed..0000000 --- a/WebCore/platform/graphics/android/TileSet.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2010, 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 TileSet_h -#define TileSet_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "BaseTile.h" -#include "Vector.h" - -namespace WebCore { - -/** - * This purpose of this class is to act as a container for BaseTiles that need - * to upload their contents to the GPU. A TiledPage creates a new TileSet and - * provides the set with identifying characteristics of the TiledPage's current - * state (see constructor). This information allows the consumer of the TileSet - * to determine if an equivalent TileSet already exists in the upload pipeline. - */ -class TileSet { -public: - TileSet(TiledPage* tiledPage, int nbRows, int nbCols); - ~TileSet(); - - bool operator==(const TileSet& set); - void paint(); - - void add(BaseTile* texture) - { - m_tiles.append(texture); - } - - TiledPage* page() - { - return m_tiledPage; - } - - unsigned int size() - { - return m_tiles.size(); - } - -private: - Vector<BaseTile*> m_tiles; - - TiledPage* m_tiledPage; - int m_nbRows; - int m_nbCols; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // TileSet_h diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp index 6f910a3..5212871 100644 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ b/WebCore/platform/graphics/android/TiledPage.cpp @@ -30,7 +30,7 @@ #include "GLUtils.h" #include "IntRect.h" -#include "PaintTileSetOperation.h" +#include "PaintTileOperation.h" #include "TilesManager.h" #ifdef DEBUG @@ -82,7 +82,6 @@ void TiledPage::updateBaseTileSize() int baseTileSize = TilesManager::instance()->maxTextureCount() + 1; if (baseTileSize > m_baseTileSize) m_baseTileSize = baseTileSize; - XLOG("Allocate %d tiles", m_baseTileSize); } TiledPage::~TiledPage() @@ -126,6 +125,7 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth)); const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight)); + XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY); // We defer marking the tile as dirty until the next time we need to prepare // to draw. m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op); @@ -133,12 +133,10 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC m_latestPictureInval = pictureCount; } -void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set) +void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds) { if (y < 0) return; - if (!set) - return; for (int i = 0; i < tilesInRow; i++) { int x = firstTileX; @@ -177,12 +175,41 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y // ensure there is a texture associated with the tile and then check to // see if the texture is dirty and in need of repainting currentTile->reserveTexture(); - if (currentTile->isDirty()) - set->add(currentTile); + updateTileUsedLevel(tileBounds, *currentTile); + if (currentTile->isDirty() && !currentTile->isRepaintPending()) { + PaintTileOperation *operation = new PaintTileOperation(currentTile); + TilesManager::instance()->scheduleOperation(operation); + } else if (currentTile->isDirty()) { + XLOG("Tile %dx%d is dirty, but awaiting repaint", currentTile->x(), currentTile->y()); + } } } } +void TiledPage::updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile) +{ + const int lastTileX = tileBounds.fRight - 1; + const int lastTileY = tileBounds.fBottom - 1; + + // set the used level of the tile (e.g. distance from the viewport) + int dx = 0; + int dy = 0; + + if (tileBounds.fLeft > tile.x()) + dx = tileBounds.fLeft - tile.x(); + else if (lastTileX < tile.x()) + dx = tile.x() - lastTileX; + + if (tileBounds.fTop > tile.y()) + dy = tileBounds.fTop - tile.y(); + else if (lastTileY < tile.y()) + dy = tile.y() - lastTileY; + + int d = std::max(dx, dy); + + tile.setUsedLevel(d); +} + void TiledPage::updateTileState(const SkIRect& tileBounds) { if (!m_glWebViewState || tileBounds.isEmpty()) { @@ -191,41 +218,19 @@ void TiledPage::updateTileState(const SkIRect& tileBounds) return; } - const int nbTilesWidth = tileBounds.width() - 1; - const int nbTilesHeight = tileBounds.height() - 1; - - const int lastTileX = tileBounds.fRight - 1; - const int lastTileY = tileBounds.fBottom - 1; - for (int x = 0; x < m_baseTileSize; x++) { BaseTile& tile = m_baseTiles[x]; - // if the tile is in the dirty region then we must invalidate it - if (m_invalRegion.contains(tile.x(), tile.y())) - tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion); - // if the tile no longer has a texture then proceed to the next tile if (tile.isAvailable()) continue; - // set the used level of the tile (e.g. distance from the viewport) - int dx = 0; - int dy = 0; - - if (tileBounds.fLeft > tile.x()) - dx = tileBounds.fLeft - tile.x(); - else if (lastTileX < tile.x()) - dx = tile.x() - lastTileX; - - if (tileBounds.fTop > tile.y()) - dy = tileBounds.fTop - tile.y(); - else if (lastTileY < tile.y()) - dy = tile.y() - lastTileY; - - int d = std::max(dx, dy); + // if the tile is in the dirty region then we must invalidate it + if (m_invalRegion.contains(tile.x(), tile.y())) + tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion); - tile.setUsedLevel(d); + updateTileUsedLevel(tileBounds, tile); } // clear the invalidated region as all tiles within that region have now @@ -234,8 +239,7 @@ void TiledPage::updateTileState(const SkIRect& tileBounds) m_invalTilesRegion.setEmpty(); } -void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, - bool scheduleFirst) +void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds) { if (!m_glWebViewState) return; @@ -243,6 +247,7 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound // update the tiles distance from the viewport updateTileState(tileBounds); m_prepare = true; + m_scrollingDown = goingDown; int firstTileX = tileBounds.fLeft; int firstTileY = tileBounds.fTop; @@ -255,43 +260,29 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound const int baseContentHeight = m_glWebViewState->baseContentHeight(); const int baseContentWidth = m_glWebViewState->baseContentWidth(); - TileSet* set = new TileSet(this, nbTilesHeight, nbTilesWidth); - - if (!scheduleFirst) { - // Expand number of tiles to allow tiles outside of viewport to be prepared for - // smoother scrolling. - int nTilesToPrepare = nbTilesWidth * nbTilesHeight; - int nMaxTilesPerPage = m_baseTileSize / 2; - int expandX = TilesManager::instance()->expandedTileBoundsX(); - int expandY = TilesManager::instance()->expandedTileBoundsY(); - if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) { - firstTileX -= expandX; - lastTileX += expandX; - nbTilesWidth += expandX * 2; - } - if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) { - firstTileY -= expandY; - lastTileY += expandY; - nbTilesHeight += expandY * 2; - } + // Expand number of tiles to allow tiles outside of viewport to be prepared for + // smoother scrolling. + int nTilesToPrepare = nbTilesWidth * nbTilesHeight; + int nMaxTilesPerPage = m_baseTileSize / 2; + int expandX = TilesManager::instance()->expandedTileBoundsX(); + int expandY = TilesManager::instance()->expandedTileBoundsY(); + if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) { + firstTileX -= expandX; + lastTileX += expandX; + nbTilesWidth += expandX * 2; } - - // We chose to prepare tiles depending on the scroll direction. Tiles are - // appended to the list and the texture uploader goes through the list front - // to back. So we append tiles in reverse order because the last additions - // to the are processed first. - if (goingDown) { - for (int i = 0; i < nbTilesHeight; i++) - prepareRow(goingLeft, nbTilesWidth, firstTileX, lastTileY - i, set); - } else { - for (int i = 0; i < nbTilesHeight; i++) - prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, set); + if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) { + firstTileY -= expandY; + lastTileY += expandY; + nbTilesHeight += expandY * 2; } + m_expandedTileBounds.fLeft = firstTileX; + m_expandedTileBounds.fTop = firstTileY; + m_expandedTileBounds.fRight = lastTileX; + m_expandedTileBounds.fBottom = lastTileY; - // The paint operation will take ownership of the tileSet here, so no delete - // is necessary. - PaintTileSetOperation* operation = new PaintTileSetOperation(set); - TilesManager::instance()->scheduleOperation(operation, scheduleFirst); + for (int i = 0; i < nbTilesHeight; i++) + prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, tileBounds); } bool TiledPage::ready(const SkIRect& tileBounds, float scale) @@ -330,7 +321,6 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds) actualTileBounds.fLeft -= TilesManager::instance()->expandedTileBoundsX(); actualTileBounds.fRight += TilesManager::instance()->expandedTileBoundsX(); - XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency); for (int j = 0; j < m_baseTileSize; j++) { BaseTile& tile = m_baseTiles[j]; if (actualTileBounds.contains(tile.x(), tile.y())) { @@ -344,11 +334,6 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds) tile.draw(transparency, rect, m_scale); } } - -#ifdef DEBUG - XLOG("FINISHED WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency); - TilesManager::instance()->printTextures(); -#endif // DEBUG } unsigned int TiledPage::paintBaseLayerContent(SkCanvas* canvas) diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h index 7e0bb2e..1aa3e61 100644 --- a/WebCore/platform/graphics/android/TiledPage.h +++ b/WebCore/platform/graphics/android/TiledPage.h @@ -31,7 +31,6 @@ #include "BaseTile.h" #include "SkCanvas.h" #include "SkRegion.h" -#include "TileSet.h" namespace WebCore { @@ -57,8 +56,7 @@ public: TiledPage* sibling(); // prepare the page for display on the screen - void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, - bool scheduleFirst = false); + void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds); // check to see if the page is ready for display bool ready(const SkIRect& tileBounds, float scale); // draw the page on the screen @@ -75,10 +73,13 @@ public: void invalidateRect(const IntRect& invalRect, const unsigned int pictureCount); void setUsable(bool usable); void updateBaseTileSize(); + bool scrollingDown() { return m_scrollingDown; } + SkIRect* expandedTileBounds() { return &m_expandedTileBounds; } private: void updateTileState(const SkIRect& tileBounds); - void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set); + void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds); + void updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile); BaseTile* getBaseTile(int x, int y) const; @@ -103,6 +104,8 @@ private: SkRegion m_invalTilesRegion; unsigned int m_latestPictureInval; bool m_prepare; + bool m_scrollingDown; + SkIRect m_expandedTileBounds; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h index 5a4e28a..6d49cca 100644 --- a/WebCore/platform/graphics/android/TilesManager.h +++ b/WebCore/platform/graphics/android/TilesManager.h @@ -39,8 +39,6 @@ namespace WebCore { -class TileSet; - class TilesManager { public: static TilesManager* instance(); @@ -57,6 +55,11 @@ public: m_pixmapsGenerationThread->removeOperationsForPage(page); } + void removePaintOperationsForPage(TiledPage* page, bool waitForCompletion) + { + m_pixmapsGenerationThread->removePaintOperationsForPage(page, waitForCompletion); + } + void removeOperationsForBaseLayer(BaseLayerAndroid* layer) { m_pixmapsGenerationThread->removeOperationsForBaseLayer(layer); @@ -67,9 +70,9 @@ public: m_pixmapsGenerationThread->removeOperationsForTexture(texture); } - void scheduleOperation(QueuedOperation* operation, bool scheduleFirst = false) + void scheduleOperation(QueuedOperation* operation) { - m_pixmapsGenerationThread->scheduleOperation(operation, scheduleFirst); + m_pixmapsGenerationThread->scheduleOperation(operation); } ShaderProgram* shader() { return &m_shader; } |