summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/LayerAndroid.cpp
diff options
context:
space:
mode:
authorNicolas Roard <nicolas@android.com>2011-02-01 03:58:44 -0800
committerNicolas Roard <nicolas@android.com>2011-02-01 04:22:24 -0800
commit3a3a8a5cdda72d79add3d08082523d5115cb47a8 (patch)
treed8d0b14c6daad8bef1bf022c996648d77bc7ffad /WebCore/platform/graphics/android/LayerAndroid.cpp
parentd7c28d82f1f7f97cd9527fc6372596fbf69bd2fd (diff)
downloadexternal_webkit-3a3a8a5cdda72d79add3d08082523d5115cb47a8.zip
external_webkit-3a3a8a5cdda72d79add3d08082523d5115cb47a8.tar.gz
external_webkit-3a3a8a5cdda72d79add3d08082523d5115cb47a8.tar.bz2
Implement automatic texture size allocation for layers
This fix several issues (3d transforms, etc.) and in general makes websites using layers snappier (gmail, etc.) bug:3367038 bug:3367048 Change-Id: Ib178416209c3636c7700296978a1f35a7a54ee22
Diffstat (limited to 'WebCore/platform/graphics/android/LayerAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp83
1 files changed, 75 insertions, 8 deletions
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);