Bug 779511 - Freeing buffers should be moved out of finalize functions. r=kats
authorpushkarsingh <pushkar.singh93@gmail.com>
Wed, 17 Oct 2012 23:53:40 -0400
changeset 110632 0883b53129b9f7767ec1f25304fd37163186f624
parent 110631 67f8d99d80fb6a29987b1e03f6bd0e4e451646a1
child 110633 40cca178608aaa7f859c6b607a42a80b63ef3ffe
push id23704
push useremorley@mozilla.com
push dateThu, 18 Oct 2012 17:12:58 +0000
treeherdermozilla-central@3779eb3f036f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs779511
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 779511 - Freeing buffers should be moved out of finalize functions. r=kats
mobile/android/base/gfx/BufferedCairoImage.java
mobile/android/base/gfx/CairoImage.java
mobile/android/base/gfx/CheckerboardImage.java
mobile/android/base/gfx/LayerRenderer.java
mobile/android/base/gfx/LayerView.java
mobile/android/base/gfx/ScreenshotLayer.java
mobile/android/base/gfx/TileLayer.java
--- a/mobile/android/base/gfx/BufferedCairoImage.java
+++ b/mobile/android/base/gfx/BufferedCairoImage.java
@@ -3,25 +3,28 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.gfx;
 
 import org.mozilla.gecko.mozglue.DirectBufferAllocator;
 
 import android.graphics.Bitmap;
+import android.util.Log;
 
 import java.nio.ByteBuffer;
 
 /** A Cairo image that simply saves a buffer of pixel data. */
 public class BufferedCairoImage extends CairoImage {
     private ByteBuffer mBuffer;
     private IntSize mSize;
     private int mFormat;
 
+    private static String LOGTAG = "GeckoBufferedCairoImage";
+
     /** Creates a buffered Cairo image from a byte buffer. */
     public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
         setBuffer(inBuffer, inWidth, inHeight, inFormat);
     }
 
     /** Creates a buffered Cairo image from an Android bitmap. */
     public BufferedCairoImage(Bitmap bitmap) {
         setBitmap(bitmap);
@@ -36,16 +39,25 @@ public class BufferedCairoImage extends 
         try {
             freeBuffer();
         } finally {
             super.finalize();
         }
     }
 
     @Override
+    public void destroy() {
+        try {
+            freeBuffer();
+        } catch (Exception ex) {
+            Log.e(LOGTAG, "error clearing buffer: ", ex);
+        }
+    }
+
+    @Override
     public ByteBuffer getBuffer() { return mBuffer; }
     @Override
     public IntSize getSize() { return mSize; }
     @Override
     public int getFormat() { return mFormat; }
 
 
     public void setBuffer(ByteBuffer buffer, int width, int height, int format) {
--- a/mobile/android/base/gfx/CairoImage.java
+++ b/mobile/android/base/gfx/CairoImage.java
@@ -8,16 +8,18 @@ package org.mozilla.gecko.gfx;
 import java.nio.ByteBuffer;
 
 /*
  * A bitmap with pixel data in one of the formats that Cairo understands.
  */
 public abstract class CairoImage {
     public abstract ByteBuffer getBuffer();
 
+    public abstract void destroy();
+
     public abstract IntSize getSize();
     public abstract int getFormat();
 
     public static final int FORMAT_INVALID = -1;
     public static final int FORMAT_ARGB32 = 0;
     public static final int FORMAT_RGB24 = 1;
     public static final int FORMAT_A8 = 2;
     public static final int FORMAT_A1 = 3;
--- a/mobile/android/base/gfx/CheckerboardImage.java
+++ b/mobile/android/base/gfx/CheckerboardImage.java
@@ -3,32 +3,35 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.gfx;
 
 import org.mozilla.gecko.mozglue.DirectBufferAllocator;
 
 import android.graphics.Color;
+import android.util.Log;
 
 import java.nio.ByteBuffer;
 import java.nio.ShortBuffer;
 import java.util.Arrays;
 
 /** A Cairo image that displays a tinted checkerboard. */
 public class CheckerboardImage extends CairoImage {
     // The width and height of the checkerboard tile.
     private static final int SIZE = 16;
     // The pixel format of the checkerboard tile.
     private static final int FORMAT = CairoImage.FORMAT_RGB16_565;
     // The color to mix in to tint the background color.
     private static final int TINT_COLOR = Color.GRAY;
     // The amount to mix in.
     private static final float TINT_OPACITY = 0.4f;
 
+    private static String LOGTAG = "GeckoCheckerboardImage";
+
     private ByteBuffer mBuffer;
     private int mMainColor;
     private boolean mShowChecks;
 
     /** Creates a new checkerboard image. */
     public CheckerboardImage() {
         int bpp = CairoUtils.bitsPerPixelForCairoFormat(FORMAT);
         mBuffer = DirectBufferAllocator.allocate(SIZE * SIZE * bpp / 8);
@@ -117,16 +120,26 @@ public class CheckerboardImage extends C
             DirectBufferAllocator.free(mBuffer);
             mBuffer = null;
         } finally {
             super.finalize();
         }
     }
 
     @Override
+    public void destroy() {
+        try {
+            DirectBufferAllocator.free(mBuffer);
+            mBuffer = null;
+        } catch (Exception ex) {
+            Log.e(LOGTAG, "error clearing buffer: ", ex);
+        }
+    }
+
+    @Override
     public ByteBuffer getBuffer() {
         return mBuffer;
     }
 
     @Override
     public IntSize getSize() {
         return new IntSize(SIZE, SIZE);
     }
--- a/mobile/android/base/gfx/LayerRenderer.java
+++ b/mobile/android/base/gfx/LayerRenderer.java
@@ -174,16 +174,30 @@ public class LayerRenderer {
             DirectBufferAllocator.free(mCoordByteBuffer);
             mCoordByteBuffer = null;
             mCoordBuffer = null;
         } finally {
             super.finalize();
         }
     }
 
+    public void destroy() {
+        DirectBufferAllocator.free(mCoordByteBuffer);
+        mCoordByteBuffer = null;
+        mCoordBuffer = null;
+        mScreenshotLayer.destroy();
+        mBackgroundLayer.destroy();
+        mShadowLayer.destroy();
+        mHorizScrollLayer.destroy();
+        mVertScrollLayer.destroy();
+        if (mFrameRateLayer != null) {
+            mFrameRateLayer.destroy();
+        }
+    }
+
     void onSurfaceCreated(EGLConfig config) {
         checkMonitoringEnabled();
         createDefaultProgram();
         activateDefaultProgram();
     }
 
     public void createDefaultProgram() {
         int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, DEFAULT_VERTEX_SHADER);
--- a/mobile/android/base/gfx/LayerView.java
+++ b/mobile/android/base/gfx/LayerView.java
@@ -107,16 +107,19 @@ public class LayerView extends FrameLayo
 
         GeckoAccessibility.setDelegate(this);
     }
 
     public void destroy() {
         if (mLayerClient != null) {
             mLayerClient.destroy();
         }
+        if (mRenderer != null) {
+            mRenderer.destroy();
+        }
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
             requestFocus();
 
         /** We need to manually hide FormAssistPopup because it is not a regular PopupWindow. */
--- a/mobile/android/base/gfx/ScreenshotLayer.java
+++ b/mobile/android/base/gfx/ScreenshotLayer.java
@@ -110,16 +110,26 @@ public class ScreenshotLayer extends Sin
             try {
                 DirectBufferAllocator.free(mBuffer);
                 mBuffer = null;
             } finally {
                 super.finalize();
             }
         }
 
+        @Override
+        public void destroy() {
+            try {
+                DirectBufferAllocator.free(mBuffer);
+                mBuffer = null;
+            } catch (Exception ex) {
+                Log.e(LOGTAG, "error clearing buffers: ", ex);
+            }
+        }
+
         void copyBuffer(ByteBuffer src, ByteBuffer dst, Rect rect, int stride) {
             int start = (rect.top * stride) + (rect.left * BYTES_FOR_16BPP);
             int end = ((rect.bottom - 1) * stride) + (rect.right * BYTES_FOR_16BPP);
             // clamp stuff just to be safe
             start = Math.max(0, Math.min(dst.limit(), Math.min(src.limit(), start)));
             end = Math.max(start, Math.min(dst.limit(), Math.min(src.capacity(), end)));
             dst.position(start);
             src.position(start).limit(end);
--- a/mobile/android/base/gfx/TileLayer.java
+++ b/mobile/android/base/gfx/TileLayer.java
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.gfx;
 
 import android.graphics.Rect;
 import android.opengl.GLES20;
+import android.util.Log;
 
 import java.nio.ByteBuffer;
 
 /**
  * Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL
  * ES.
  */
 public abstract class TileLayer extends Layer {
@@ -45,16 +46,26 @@ public abstract class TileLayer extends 
         try {
             if (mTextureIDs != null)
                 TextureReaper.get().add(mTextureIDs);
         } finally {
             super.finalize();
         }
     }
 
+    public void destroy() {
+        try {
+            if (mImage != null) {
+                mImage.destroy();
+            }
+        } catch (Exception ex) {
+            Log.e(LOGTAG, "error clearing buffers: ", ex);
+        }
+    }
+
     public void setPaintMode(PaintMode mode) {
         mPaintMode = mode;
     }
 
     /**
      * Invalidates the entire buffer so that it will be uploaded again. Only valid inside a
      * transaction.
      */