summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2012-05-11 16:03:54 -0700
committerChris Craik <ccraik@google.com>2012-05-14 11:15:04 -0700
commit425ef23631e3468c61a5740dd4e4bae3052cec48 (patch)
tree756f4ce43978ca025638653a06024d1d8661ffce /Source/WebCore/platform/graphics/android
parentd236e597b13a93d21eafa2edeacb5092076937e1 (diff)
downloadexternal_webkit-425ef23631e3468c61a5740dd4e4bae3052cec48.zip
external_webkit-425ef23631e3468c61a5740dd4e4bae3052cec48.tar.gz
external_webkit-425ef23631e3468c61a5740dd4e4bae3052cec48.tar.bz2
Fix stale tile problem
bug:6483791 Update tile painter of outstanding operations Always schedule a paint operation if we can't update an outstanding one Remove old interruption code, as it's no longer used Change-Id: Ibcdb142d3d9b4ee7a52c78b5c121056089913211
Diffstat (limited to 'Source/WebCore/platform/graphics/android')
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h1
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp51
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h8
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.h9
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp19
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h4
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