diff options
author | Bart Sears <bsears@google.com> | 2011-02-01 06:50:34 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-02-01 06:50:34 -0800 |
commit | b6c19867b135073314a532f329edec0e717a4f0b (patch) | |
tree | 6ae1239ddf96239d8e5faafd49ddda670be9bb97 /WebCore/platform | |
parent | f09d842c6d6d0b10ceaf6619d540a8c3f9056922 (diff) | |
parent | 3a3a8a5cdda72d79add3d08082523d5115cb47a8 (diff) | |
download | external_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')
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(); |