diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/android')
6 files changed, 61 insertions, 26 deletions
diff --git a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp index 05defc9..87096b0 100644 --- a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp @@ -34,6 +34,7 @@ #include "ImageTexture.h" #include "ImagesManager.h" #include "LayerAndroid.h" +#include "TexturesGenerator.h" #include "TilesManager.h" namespace WebCore { @@ -89,9 +90,9 @@ int PaintTileOperation::priority() int priority = 200000; - // prioritize low res while scrolling + // prioritize low res while scrolling, otherwise set priority above gDeferPriorityCutoff if (m_isLowResPrefetch) - priority = m_state->isScrolling() ? 0 : 400000; + priority = m_state->isScrolling() ? 0 : TexturesGenerator::gDeferPriorityCutoff; // prioritize higher draw count unsigned long long currentDraw = TilesManager::instance()->getDrawGLCount(); diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp index dd645d9..cc94c9c 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp @@ -51,12 +51,20 @@ bool TexturesGenerator::tryUpdateOperationWithPainter(Tile* tile, TilePainter* p void TexturesGenerator::scheduleOperation(QueuedOperation* operation) { + bool signal = false; { android::Mutex::Autolock lock(mRequestedOperationsLock); mRequestedOperations.append(operation); mRequestedOperationsHash.set(operation->uniquePtr(), operation); + + bool deferrable = operation->priority() >= gDeferPriorityCutoff; + m_deferredMode &= deferrable; + + // signal if we weren't in deferred mode, or if we can no longer defer + signal = !m_deferredMode || !deferrable; } - mRequestedOperationsCond.signal(); + if (signal) + mRequestedOperationsCond.signal(); } void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter) @@ -115,6 +123,13 @@ QueuedOperation* TexturesGenerator::popNext() currentIndex = i; } } + + if (!m_deferredMode && currentPriority >= gDeferPriorityCutoff) { + // finished with non-deferred rendering, enter deferred mode to wait + m_deferredMode = true; + return 0; + } + mRequestedOperations.remove(currentIndex); mRequestedOperationsHash.remove(current->uniquePtr()); return current; @@ -124,36 +139,46 @@ bool TexturesGenerator::threadLoop() { // Check if we have any pending operations. mRequestedOperationsLock.lock(); - while (!mRequestedOperations.size()) - mRequestedOperationsCond.wait(mRequestedOperationsLock); - ALOGV("threadLoop, got signal"); + if (!m_deferredMode) { + // if we aren't currently deferring work, wait for new work to arrive + while (!mRequestedOperations.size()) + mRequestedOperationsCond.wait(mRequestedOperationsLock); + } else { + // if we only have deferred work, wait for better work, or a timeout + mRequestedOperationsCond.waitRelative(mRequestedOperationsLock, gDeferNsecs); + } + mRequestedOperationsLock.unlock(); - m_currentOperation = 0; bool stop = false; while (!stop) { + QueuedOperation* currentOperation = 0; + mRequestedOperationsLock.lock(); ALOGV("threadLoop, %d operations in the queue", mRequestedOperations.size()); + if (mRequestedOperations.size()) - m_currentOperation = popNext(); + currentOperation = popNext(); mRequestedOperationsLock.unlock(); - if (m_currentOperation) { + if (currentOperation) { ALOGV("threadLoop, painting the request with priority %d", - m_currentOperation->priority()); - m_currentOperation->run(); + currentOperation->priority()); + currentOperation->run(); } - QueuedOperation* oldOperation = m_currentOperation; mRequestedOperationsLock.lock(); - if (m_currentOperation) - m_currentOperation = 0; - if (!mRequestedOperations.size()) + if (m_deferredMode && !currentOperation) stop = true; + if (!mRequestedOperations.size()) { + m_deferredMode = false; + stop = true; + } mRequestedOperationsLock.unlock(); - if (oldOperation) - delete oldOperation; // delete outside lock + + if (currentOperation) + delete currentOperation; // delete outside lock } ALOGV("threadLoop empty"); diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h index bc4fe1e..290ad08 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h +++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h @@ -44,8 +44,8 @@ class TilesManager; class TexturesGenerator : public Thread { public: TexturesGenerator(TilesManager* instance) : Thread(false) - , m_currentOperation(0) - , m_tilesManager(instance) { } + , m_tilesManager(instance) + , m_deferredMode(false) { } virtual ~TexturesGenerator() { } virtual status_t readyToRun(); @@ -55,6 +55,10 @@ public: void scheduleOperation(QueuedOperation* operation); + // low res tiles are put at or above this cutoff when not scrolling, + // signifying that they should be deferred + static const int gDeferPriorityCutoff = 500000000; + private: QueuedOperation* popNext(); virtual bool threadLoop(); @@ -62,8 +66,13 @@ private: WTF::HashMap<void*, QueuedOperation*> mRequestedOperationsHash; android::Mutex mRequestedOperationsLock; android::Condition mRequestedOperationsCond; - QueuedOperation* m_currentOperation; TilesManager* m_tilesManager; + + bool m_deferredMode; + + // defer painting for one second if best in queue has priority + // QueuedOperation::gDeferPriorityCutoff or higher + static const nsecs_t gDeferNsecs = 1000000000; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp index 2e2c397..e674884 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp @@ -54,7 +54,7 @@ Tile::Tile(bool isLayerTile) , m_backTexture(0) , m_scale(1) , m_dirty(true) - , m_repaintPending(false) + , m_repaintsPending(0) , m_fullRepaint(true) , m_isLayerTile(isLayerTile) , m_drawCount(0) @@ -212,13 +212,13 @@ bool Tile::isDirty() bool Tile::isRepaintPending() { android::AutoMutex lock(m_atomicSync); - return m_repaintPending; + return m_repaintsPending != 0; } void Tile::setRepaintPending(bool pending) { android::AutoMutex lock(m_atomicSync); - m_repaintPending = pending; + m_repaintsPending += pending ? 1 : -1; } bool Tile::drawGL(float opacity, const SkRect& rect, float scale, diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h index 4c8052c..2dc5414 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.h +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h @@ -157,8 +157,8 @@ private: // redrawn in the backTexture bool m_dirty; - // used to signal that a repaint is pending - bool m_repaintPending; + // number of repaints pending + int m_repaintsPending; // store the dirty region SkRegion m_dirtyArea; diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index d0a9f27..3487acd 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -248,7 +248,7 @@ void TileGrid::prepareTile(int x, int y, TilePainter* painter, if (tile->isRepaintPending() && tilesManager->tryUpdateOperationWithPainter(tile, painter)) return; - ALOGV("painting TG %p's tile %d %d for LG %p", this, x, y, painter); + ALOGV("painting TG %p's tile %d %d for LG %p, scale %f", this, x, y, painter, m_scale); PaintTileOperation *operation = new PaintTileOperation(tile, painter, state, isLowResPrefetch); tilesManager->scheduleOperation(operation); |