OSDN Git Service

Fix ANR when hitting very large layers
authorNicolas Roard <nicolasroard@google.com>
Fri, 9 Dec 2011 00:50:32 +0000 (16:50 -0800)
committerNicolas Roard <nicolasroard@google.com>
Fri, 9 Dec 2011 00:50:32 +0000 (16:50 -0800)
In some cases we have to deal with very large layers (e.g. 130k x 56k).
We do clip them at draw time, but at prepare time we will generate *all* the
needed BaseTile objects. Those are small, but when you have to allocated
100k of them and then iterate, it does not make things fast, and we can
ANR (and sometimes recover later).

bug:5466840
Change-Id: I01c64ed1014fa719b619609fd2bd24126dc9056e

Source/WebCore/platform/graphics/android/PaintedSurface.cpp

index d3c1e15..45c7579 100644 (file)
@@ -52,9 +52,8 @@
 
 #endif // DEBUG
 
-// Allows layers using less than MAX_UNCLIPPED_AREA tiles to
-// schedule all of them instead of clipping the area with the visible rect.
-#define MAX_UNCLIPPED_AREA 16
+// Layers with an area larger than 2048*2048 should never be unclipped
+#define MAX_UNCLIPPED_AREA 4194304
 
 namespace WebCore {
 
@@ -203,10 +202,14 @@ IntRect PaintedSurface::computeVisibleArea(LayerAndroid* layer) {
         return area;
 
     if (!layer->contentIsScrollable()
-        && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures)
+        && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
         area = layer->unclippedArea();
-    else
+        double total = ((double) area.width()) * ((double) area.height());
+        if (total > MAX_UNCLIPPED_AREA)
+            area = layer->visibleArea();
+    } else {
         area = layer->visibleArea();
+    }
 
     return area;
 }