summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2012-05-10 18:03:49 -0700
committerChris Craik <ccraik@google.com>2012-05-14 18:24:01 -0700
commit55ff9f5ac537f2b11ae997f1029bdccb87008825 (patch)
treee51e6c7103d4fe46a0565cc53ed4815e245ef61d
parent4ef88beceb0e8d5b2df5bd4e30360ffcb8c2a65d (diff)
downloadexternal_webkit-55ff9f5ac537f2b11ae997f1029bdccb87008825.zip
external_webkit-55ff9f5ac537f2b11ae997f1029bdccb87008825.tar.gz
external_webkit-55ff9f5ac537f2b11ae997f1029bdccb87008825.tar.bz2
Defer low res tile rendering to once/second
bug:6434846 Change-Id: I5ba981e6a3e154a1e99873d8fd5317b8ce7bb73b
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp55
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h15
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp2
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);