diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/android')
10 files changed, 54 insertions, 63 deletions
diff --git a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp index fcd9d3b..05defc9 100644 --- a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp @@ -116,4 +116,14 @@ int PaintTileOperation::priority() return priority; } +void PaintTileOperation::updatePainter(TilePainter* painter) +{ + if (m_painter == painter) + return; + + SkSafeRef(painter); + SkSafeUnref(m_painter); + m_painter = painter; +} + } diff --git a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h index 1d376bf..c82cdcd 100644 --- a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h +++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h @@ -43,9 +43,12 @@ public: virtual ~PaintTileOperation(); virtual bool operator==(const QueuedOperation* operation); virtual void run(); + virtual void* uniquePtr() { return m_tile; } // returns a rendering priority for m_tile, lower values are processed faster virtual int priority(); + TilePainter* painter() { return m_painter; } + void updatePainter(TilePainter* painter); float scale() { return m_tile->scale(); } private: diff --git a/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h b/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h index f98efcd..7625528 100644 --- a/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h +++ b/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h @@ -33,6 +33,7 @@ public: virtual ~QueuedOperation() {} virtual void run() = 0; virtual bool operator==(const QueuedOperation* operation) = 0; + virtual void* uniquePtr() = 0; virtual int priority() = 0; }; diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index 7dd16dc..3b26ebc 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp @@ -351,7 +351,7 @@ bool Surface::paint(SkCanvas* canvas) if (isBase() && getFirstLayer()->countChildren() && getFirstLayer()->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) { - for (unsigned int i = 0; i < getFirstLayer()->countChildren(); i++) + for (int i = 0; i < getFirstLayer()->countChildren(); i++) getFirstLayer()->getChild(i)->drawCanvas(canvas, true, Layer::FlattenedLayers); } } else { diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp index f884e52..dd645d9 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp @@ -39,16 +39,27 @@ namespace WebCore { +bool TexturesGenerator::tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter) +{ + android::Mutex::Autolock lock(mRequestedOperationsLock); + if (!mRequestedOperationsHash.contains(tile)) + return false; + + static_cast<PaintTileOperation*>(mRequestedOperationsHash.get(tile))->updatePainter(painter); + return true; +} + void TexturesGenerator::scheduleOperation(QueuedOperation* operation) { { android::Mutex::Autolock lock(mRequestedOperationsLock); mRequestedOperations.append(operation); + mRequestedOperationsHash.set(operation->uniquePtr(), operation); } mRequestedOperationsCond.signal(); } -void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning) +void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter) { if (!filter) return; @@ -58,39 +69,13 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool QueuedOperation* operation = mRequestedOperations[i]; if (filter->check(operation)) { mRequestedOperations.remove(i); + mRequestedOperationsHash.remove(operation->uniquePtr()); delete operation; } else { i++; } } - - if (waitForRunning && m_currentOperation) { - QueuedOperation* operation = m_currentOperation; - - if (operation && filter->check(operation)) { - m_waitForCompletion = true; - // The reason we are signaling the transferQueue is : - // TransferQueue may be waiting a slot to work on, but now UI - // thread is waiting for Tex Gen thread to finish first before the - // UI thread can free a slot for the transferQueue. - // Therefore, it could be a deadlock. - // The solution is use this as a flag to tell Tex Gen thread that - // UI thread is waiting now, Tex Gen thread should not wait for the - // queue any more. - m_tilesManager->transferQueue()->interruptTransferQueue(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; - } + delete filter; } status_t TexturesGenerator::readyToRun() @@ -108,6 +93,7 @@ QueuedOperation* TexturesGenerator::popNext() int currentPriority = current->priority(); if (currentPriority < 0) { mRequestedOperations.removeLast(); + mRequestedOperationsHash.remove(current->uniquePtr()); return current; } int currentIndex = mRequestedOperations.size() - 1; @@ -118,6 +104,7 @@ QueuedOperation* TexturesGenerator::popNext() if (nextPriority < 0) { // Found a very high priority item, go ahead and just handle it now mRequestedOperations.remove(i); + mRequestedOperationsHash.remove(next->uniquePtr()); return next; } // pick items preferrably by priority, or if equal, by order of @@ -129,6 +116,7 @@ QueuedOperation* TexturesGenerator::popNext() } } mRequestedOperations.remove(currentIndex); + mRequestedOperationsHash.remove(current->uniquePtr()); return current; } @@ -163,11 +151,6 @@ bool TexturesGenerator::threadLoop() m_currentOperation = 0; if (!mRequestedOperations.size()) stop = true; - if (m_waitForCompletion) { - m_waitForCompletion = false; - m_tilesManager->transferQueue()->interruptTransferQueue(false); - mRequestedOperationsCond.signal(); - } mRequestedOperationsLock.unlock(); if (oldOperation) delete oldOperation; // delete outside lock diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h index 08f69ae..bc4fe1e 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h +++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h @@ -30,6 +30,7 @@ #include "QueuedOperation.h" #include "TilePainter.h" +#include <wtf/HashMap.h> #include <wtf/Vector.h> #include <utils/threads.h> @@ -43,13 +44,14 @@ class TilesManager; class TexturesGenerator : public Thread { public: TexturesGenerator(TilesManager* instance) : Thread(false) - , m_waitForCompletion(false) , m_currentOperation(0) , m_tilesManager(instance) { } virtual ~TexturesGenerator() { } virtual status_t readyToRun(); - void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning = true); + bool tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter); + + void removeOperationsForFilter(OperationFilter* filter); void scheduleOperation(QueuedOperation* operation); @@ -57,9 +59,9 @@ private: QueuedOperation* popNext(); virtual bool threadLoop(); WTF::Vector<QueuedOperation*> mRequestedOperations; + WTF::HashMap<void*, QueuedOperation*> mRequestedOperationsHash; android::Mutex mRequestedOperationsLock; android::Condition mRequestedOperationsCond; - bool m_waitForCompletion; QueuedOperation* m_currentOperation; TilesManager* m_tilesManager; }; diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index 7680fc9..d0a9f27 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -241,11 +241,17 @@ void TileGrid::prepareTile(int x, int y, TilePainter* painter, if (tile->isDirty() || !tile->frontTexture()) tile->reserveTexture(); - if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) { + if (tile->backTexture() && tile->isDirty()) { + TilesManager* tilesManager = TilesManager::instance(); + + // if a scheduled repaint is still outstanding, update it with the new painter + if (tile->isRepaintPending() && tilesManager->tryUpdateOperationWithPainter(tile, painter)) + return; + ALOGV("painting TG %p's tile %d %d for LG %p", this, x, y, painter); PaintTileOperation *operation = new PaintTileOperation(tile, painter, state, isLowResPrefetch); - TilesManager::instance()->scheduleOperation(operation); + tilesManager->scheduleOperation(operation); } } diff --git a/Source/WebCore/platform/graphics/android/rendering/TilesManager.h b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h index 295acf6..676d703 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h @@ -53,9 +53,14 @@ public: return gInstance != 0; } - void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning = false) + void removeOperationsForFilter(OperationFilter* filter) { - m_pixmapsGenerationThread->removeOperationsForFilter(filter, waitForRunning); + m_pixmapsGenerationThread->removeOperationsForFilter(filter); + } + + bool tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter) + { + return m_pixmapsGenerationThread->tryUpdateOperationWithPainter(tile, painter); } void scheduleOperation(QueuedOperation* operation) diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp index 2316014..41d6709 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp @@ -58,7 +58,6 @@ TransferQueue::TransferQueue(bool useMinimalMem) , m_fboID(0) , m_sharedSurfaceTextureId(0) , m_hasGLContext(true) - , m_interruptedByRemovingOp(false) , m_currentDisplay(EGL_NO_DISPLAY) , m_currentUploadType(DEFAULT_UPLOAD_TYPE) { @@ -216,17 +215,8 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, TileTexture* destTex, #endif } -void TransferQueue::interruptTransferQueue(bool interrupt) -{ - m_transferQueueItemLocks.lock(); - m_interruptedByRemovingOp = interrupt; - if (m_interruptedByRemovingOp) - m_transferQueueItemCond.signal(); - m_transferQueueItemLocks.unlock(); -} - // This function must be called inside the m_transferQueueItemLocks, for the -// wait, m_interruptedByRemovingOp and getHasGLContext(). +// wait and getHasGLContext(). // Only called by updateQueueWithBitmap() for now. bool TransferQueue::readyForUpdate() { @@ -234,13 +224,8 @@ bool TransferQueue::readyForUpdate() return false; // Don't use a while loop since when the WebView tear down, the emptyCount // will still be 0, and we bailed out b/c of GL context lost. - if (!m_emptyItemCount) { - if (m_interruptedByRemovingOp) - return false; + if (!m_emptyItemCount) m_transferQueueItemCond.wait(m_transferQueueItemLocks); - if (m_interruptedByRemovingOp) - return false; - } if (!getHasGLContext()) return false; diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h index b8563e3..44d3c37 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h @@ -131,8 +131,6 @@ public: // The lock will be done when returning true. bool readyForUpdate(); - void interruptTransferQueue(bool); - void lockQueue() { m_transferQueueItemLocks.lock(); } void unlockQueue() { m_transferQueueItemLocks.unlock(); } @@ -200,8 +198,6 @@ private: int m_emptyItemCount; - bool m_interruptedByRemovingOp; - // We are using wait/signal to handle our own queue sync. // First of all, if we don't have our own lock, then while WebView is // destroyed, the UI thread will wait for the Tex Gen to get out from |