summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
authorBart Sears <bsears@google.com>2011-02-01 06:50:34 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-02-01 06:50:34 -0800
commitb6c19867b135073314a532f329edec0e717a4f0b (patch)
tree6ae1239ddf96239d8e5faafd49ddda670be9bb97 /WebCore/platform
parentf09d842c6d6d0b10ceaf6619d540a8c3f9056922 (diff)
parent3a3a8a5cdda72d79add3d08082523d5115cb47a8 (diff)
downloadexternal_webkit-b6c19867b135073314a532f329edec0e717a4f0b.zip
external_webkit-b6c19867b135073314a532f329edec0e717a4f0b.tar.gz
external_webkit-b6c19867b135073314a532f329edec0e717a4f0b.tar.bz2
Merge "Implement automatic texture size allocation for layers This fix several issues (3d transforms, etc.) and in general makes websites using layers snappier (gmail, etc.)" into honeycomb
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp1
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp83
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h9
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp14
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h2
5 files changed, 99 insertions, 10 deletions
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index d2d515a..b632664 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -314,6 +314,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
scale = m_glWebViewState->futureScale();
}
compositedRoot->setScale(scale);
+ compositedRoot->computeTextureSize();
compositedRoot->reserveGLTextures();
#ifdef DEBUG
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 5d6d8ff..07a0e00 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -585,7 +585,7 @@ bool LayerAndroid::needsTexture()
&& m_recordingPicture->width() && m_recordingPicture->height());
}
-IntRect LayerAndroid::clippedRect()
+IntRect LayerAndroid::clippedRect() const
{
IntRect r(0, 0, getWidth(), getHeight());
IntRect tr = drawTransform().mapRect(r);
@@ -600,10 +600,20 @@ bool LayerAndroid::outsideViewport()
m_layerTextureRect.height() == 0;
}
-int LayerAndroid::countTextureSize()
+int LayerAndroid::fullTextureSize() const
+{
+ return getWidth() * m_scale * getHeight() * m_scale * 4;
+}
+
+int LayerAndroid::clippedTextureSize() const
{
IntRect cr = clippedRect();
- int size = cr.width() * cr.height() * 4;
+ return cr.width() * cr.height() * 4;
+}
+
+int LayerAndroid::countTextureSize()
+{
+ int size = clippedTextureSize();
int count = this->countChildren();
for (int i = 0; i < count; i++)
size += getChild(i)->countTextureSize();
@@ -619,6 +629,67 @@ int LayerAndroid::nbLayers()
return nb;
}
+void LayerAndroid::collect(Vector<LayerAndroid*>& layers, int& size)
+{
+ m_layerTextureRect = clippedRect();
+ if (!outsideViewport()) {
+ layers.append(this);
+ size += fullTextureSize();
+ }
+ int count = this->countChildren();
+ for (int i = 0; i < count; i++)
+ getChild(i)->collect(layers, size);
+}
+
+static inline bool compareLayerFullSize(const LayerAndroid* a, const LayerAndroid* b)
+{
+ const int sizeA = a->fullTextureSize();
+ const int sizeB = b->fullTextureSize();
+ return sizeA > sizeB;
+}
+
+void LayerAndroid::computeTextureSize()
+{
+ // First, we collect the layers, computing m_layerTextureRect
+ // as being clipped against the viewport
+ Vector <LayerAndroid*> layers;
+ int total = 0;
+ collect(layers, total);
+
+ // Then we sort them by the size the full texture would need
+ std::stable_sort(layers.begin(), layers.end(), compareLayerFullSize);
+
+ // Now, let's determinate which layer can use a full texture
+ int max = TilesManager::instance()->maxLayersAllocation();
+ int maxLayerSize = TilesManager::instance()->maxLayerAllocation();
+ XLOG("*** layers sorted by size ***");
+ XLOG("total memory needed: %d bytes (%d Mb), max %d Mb",
+ total, total / 1024 / 1024, max / 1024 / 1024);
+ for (unsigned int i = 0; i < layers.size(); i++) {
+ LayerAndroid* layer = layers[i];
+ bool clipped = true;
+ // If we are under the maximum, and the layer inspected
+ // needs a texture less than the maxLayerSize, use the full texture.
+ if ((total < max) &&
+ (layer->fullTextureSize() < maxLayerSize)) {
+ IntRect full(0, 0, layer->getWidth(), layer->getHeight());
+ layer->m_layerTextureRect = full;
+ clipped = false;
+ } else {
+ // Otherwise, the layer is clipped; update the total
+ total -= layer->fullTextureSize();
+ total += layer->clippedTextureSize();
+ }
+ XLOG("Layer %d (%.2f, %.2f) %d bytes (clipped: %s)",
+ layer->uniqueId(), layer->getWidth(), layer->getHeight(),
+ layer->fullTextureSize(),
+ clipped ? "YES" : "NO");
+ }
+ XLOG("total memory used after clipping: %d bytes (%d Mb), max %d Mb",
+ total, total / 1024 / 1024, max / 1024 / 1024);
+ XLOG("*** end of sorted layers ***");
+}
+
void LayerAndroid::showLayers(int indent)
{
IntRect cr = clippedRect();
@@ -655,14 +726,10 @@ void LayerAndroid::reserveGLTextures()
if (!needsTexture())
return;
- LayerTexture* reservedTexture = 0;
-
- // Compute the layer size & position we need (clipped to the viewport)
- m_layerTextureRect = clippedRect();
-
if (outsideViewport())
return;
+ LayerTexture* reservedTexture = 0;
reservedTexture = TilesManager::instance()->getExistingTextureForLayer(
this, m_layerTextureRect);
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index f4fea49..53e513b 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -102,7 +102,7 @@ public:
void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
FloatPoint translation() const;
SkRect bounds() const;
- IntRect clippedRect();
+ IntRect clippedRect() const;
bool outsideViewport();
// Debug/info functions
@@ -110,6 +110,13 @@ public:
int nbLayers();
void showLayers(int indent = 0);
+ // Texture size functions
+ void computeTextureSize();
+ void collect(Vector<LayerAndroid*>& layers,
+ int& size);
+ int clippedTextureSize() const;
+ int fullTextureSize() const;
+
// called on the root layer
void reserveGLTextures();
void createGLTextures();
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index 21162ff..d64a0b1 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -63,7 +63,9 @@
#define TILE_HEIGHT 300
// Define a maximum amount of ram used by layers
-#define MAX_LAYERS_ALLOCATION 20971520 // 20Mb
+#define MAX_LAYERS_ALLOCATION 33554432 // 32Mb
+// Define a maximum amount of ram used by one layer
+#define MAX_LAYER_ALLOCATION 8388608 // 8Mb
#define BYTES_PER_PIXEL 4 // 8888 config
namespace WebCore {
@@ -342,6 +344,16 @@ LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer, const Int
return texture;
}
+int TilesManager::maxLayersAllocation()
+{
+ return MAX_LAYERS_ALLOCATION;
+}
+
+int TilesManager::maxLayerAllocation()
+{
+ return MAX_LAYER_ALLOCATION;
+}
+
int TilesManager::maxTextureCount()
{
android::Mutex::Autolock lock(m_texturesLock);
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index de22242..113cc62 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -86,6 +86,8 @@ public:
void resetTextureUsage(TiledPage* page);
+ int maxLayersAllocation();
+ int maxLayerAllocation();
int maxTextureCount();
void setMaxTextureCount(int max);
static float tileWidth();