summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2011-03-23 18:02:27 -0700
committerJohn Reck <jreck@google.com>2011-05-05 14:31:39 -0700
commit0c23c9caf76a37515b4911e84606ad36a43cd74e (patch)
treee31a62e03fef93e8200624adb31a2b11c037711c
parent2d60bef786645e5b9e2da0e8374d3f06a40d0638 (diff)
downloadexternal_webkit-0c23c9caf76a37515b4911e84606ad36a43cd74e.zip
external_webkit-0c23c9caf76a37515b4911e84606ad36a43cd74e.tar.gz
external_webkit-0c23c9caf76a37515b4911e84606ad36a43cd74e.tar.bz2
DO NOT MERGE priority queue based tile manager
Removes TileSets and queues tiles individually Uses a priority queue to determine which tiles to render first Stops rendering the front tile page if we are prepping the back one Limits queue spam by tracking which tiles are already in the queue Change-Id: Idd4154b8a2771d0db2da94c84a683314597f8542
-rw-r--r--WebCore/Android.mk2
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp14
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp20
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h5
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp2
-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.h17
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.cpp102
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.h6
-rw-r--r--WebCore/platform/graphics/android/TileSet.h77
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp135
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h11
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h11
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 d58c549..36bb293 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)
@@ -166,12 +167,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 b832eee..0a03377 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; }