bug 708961 - We still use ByteBuffer.allocateDirect for large buffers r=pcwalton a=java-only

This commit is contained in:
Brad Lassey 2011-12-13 17:53:51 -05:00
parent ed3e03b515
commit 81be12ab70
5 changed files with 55 additions and 15 deletions

View File

@ -37,6 +37,7 @@
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.CairoUtils;
import android.graphics.Bitmap;
@ -46,6 +47,7 @@ import java.nio.ByteBuffer;
public class BufferedCairoImage extends CairoImage {
private ByteBuffer mBuffer;
private int mWidth, mHeight, mFormat;
private boolean mNeedToFreeBuffer = false;
/** Creates a buffered Cairo image from a byte buffer. */
public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
@ -57,11 +59,23 @@ public class BufferedCairoImage extends CairoImage {
mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig());
mWidth = bitmap.getWidth();
mHeight = bitmap.getHeight();
mBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 4);
mNeedToFreeBuffer = true;
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * 4);
bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
}
@Override
protected void finalize() throws Throwable {
try {
if (mNeedToFreeBuffer && mBuffer != null)
GeckoAppShell.freeDirectBuffer(mBuffer);
mNeedToFreeBuffer = false;
mBuffer = null;
} finally {
super.finalize();
}
}
@Override
public ByteBuffer getBuffer() { return mBuffer; }
@Override
public int getWidth() { return mWidth; }

View File

@ -103,7 +103,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
mScreenSize = new IntSize(1, 1);
mBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 2);
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * 2);
mCairoImage = new CairoImage() {
@Override
@ -119,6 +119,17 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
mTileLayer = new SingleTileLayer(mCairoImage);
}
protected void finalize() throws Throwable {
try {
if (mBuffer != null)
GeckoAppShell.freeDirectBuffer(mBuffer);
mBuffer = null;
} finally {
super.finalize();
}
}
/** Attaches the root layer to the layer controller so that Gecko appears. */
@Override
public void setLayerController(LayerController layerController) {

View File

@ -51,6 +51,7 @@ import android.util.Log;
import java.nio.ByteBuffer;
import javax.microedition.khronos.opengles.GL10;
import org.mozilla.gecko.FloatUtils;
import org.mozilla.gecko.GeckoAppShell;
/**
* Draws a small rect. This is scaled to become a scrollbar.
@ -74,6 +75,7 @@ public class ScrollbarLayer extends TileLayer {
private final Bitmap mBitmap;
private final Canvas mCanvas;
private float mOpacity;
private boolean mFinalized = false;
private ScrollbarLayer(CairoImage image, boolean vertical, ByteBuffer buffer) {
super(false, image);
@ -84,11 +86,22 @@ public class ScrollbarLayer extends TileLayer {
mCanvas = new Canvas(mBitmap);
}
protected void finalize() throws Throwable {
try {
if (!mFinalized && mBuffer != null)
GeckoAppShell.freeDirectBuffer(mBuffer);
mFinalized = true;
} finally {
super.finalize();
}
}
public static ScrollbarLayer create(boolean vertical) {
// just create an empty image for now, it will get drawn
// on demand anyway
int imageSize = nextPowerOfTwo(BAR_SIZE);
ByteBuffer buffer = ByteBuffer.allocateDirect(imageSize * imageSize * 4);
ByteBuffer buffer = GeckoAppShell.allocateDirectBuffer(imageSize * imageSize * 4);
CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize, CairoImage.FORMAT_ARGB32);
return new ScrollbarLayer(image, vertical, buffer);
}

View File

@ -37,6 +37,7 @@
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize;
@ -56,6 +57,7 @@ import java.nio.IntBuffer;
public class TextLayer extends SingleTileLayer {
private final ByteBuffer mBuffer;
private final IntSize mSize;
private boolean mFinalized = false;
/*
* This awkward pattern is necessary due to Java's restrictions on when one can call superclass
@ -68,8 +70,18 @@ public class TextLayer extends SingleTileLayer {
renderText(text);
}
protected void finalize() throws Throwable {
try {
if (!mFinalized && mBuffer != null)
GeckoAppShell.freeDirectBuffer(mBuffer);
mFinalized = true;
} finally {
super.finalize();
}
}
public static TextLayer create(IntSize size, String text) {
ByteBuffer buffer = ByteBuffer.allocateDirect(size.width * size.height * 4);
ByteBuffer buffer = GeckoAppShell.allocateDirectBuffer(size.width * size.height * 4);
BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height,
CairoImage.FORMAT_ARGB32);
return new TextLayer(buffer, image, size, text);

View File

@ -168,15 +168,5 @@ public abstract class TileLayer extends Layer {
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, repeatMode);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, repeatMode);
}
protected static FloatBuffer createBuffer(float[] values) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(values.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
floatBuffer.put(values);
floatBuffer.position(0);
return floatBuffer;
}
}