summaryrefslogtreecommitdiff
path: root/core/java/android/view/GraphicBuffer.java
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-07-09 18:56:57 -0700
committerRomain Guy <romainguy@google.com>2013-07-09 18:56:57 -0700
commitb2ed04a68913f4d84d7cb7e979b6f0ae96f43058 (patch)
tree4f1e135a2c47c11874f0840fee3f6f2783c35e8b /core/java/android/view/GraphicBuffer.java
parent525b7c020b326c2cffde67d7850c720cf3300437 (diff)
Unregister gralloc buffer immediately
Bug #9406765 Waiting for a GC to finalize the GraphicBuffer could cause ordering issues Change-Id: I7035a9eef52a6c3b44ab28f40a7b1fbdc83d2e20
Diffstat (limited to 'core/java/android/view/GraphicBuffer.java')
-rw-r--r--core/java/android/view/GraphicBuffer.java69
1 files changed, 66 insertions, 3 deletions
diff --git a/core/java/android/view/GraphicBuffer.java b/core/java/android/view/GraphicBuffer.java
index b4576f367b94..30c077c2e879 100644
--- a/core/java/android/view/GraphicBuffer.java
+++ b/core/java/android/view/GraphicBuffer.java
@@ -62,6 +62,9 @@ public class GraphicBuffer implements Parcelable {
private Canvas mCanvas;
private int mSaveCount;
+ // If set to true, this GraphicBuffer instance cannot be used anymore
+ private boolean mDestroyed;
+
/**
* Creates new <code>GraphicBuffer</code> instance. This method will return null
* if the buffer cannot be created.
@@ -128,10 +131,14 @@ public class GraphicBuffer implements Parcelable {
* <p>The content of the buffer is preserved between unlockCanvas()
* and lockCanvas().</p>
*
+ * <p>If this method is called after {@link #destroy()}, the return value will
+ * always be null.</p>
+ *
* @return A Canvas used to draw into the buffer, or null.
*
* @see #lockCanvas(android.graphics.Rect)
* @see #unlockCanvasAndPost(android.graphics.Canvas)
+ * @see #isDestroyed()
*/
public Canvas lockCanvas() {
return lockCanvas(null);
@@ -141,14 +148,22 @@ public class GraphicBuffer implements Parcelable {
* Just like {@link #lockCanvas()} but allows specification of a dirty
* rectangle.
*
+ * <p>If this method is called after {@link #destroy()}, the return value will
+ * always be null.</p>
+ *
* @param dirty Area of the buffer that may be modified.
- * @return A Canvas used to draw into the surface or null
+ * @return A Canvas used to draw into the surface, or null.
*
* @see #lockCanvas()
* @see #unlockCanvasAndPost(android.graphics.Canvas)
+ * @see #isDestroyed()
*/
public Canvas lockCanvas(Rect dirty) {
+ if (mDestroyed) {
+ return null;
+ }
+
if (mCanvas == null) {
mCanvas = new Canvas();
}
@@ -164,13 +179,17 @@ public class GraphicBuffer implements Parcelable {
/**
* Finish editing pixels in the buffer.
*
+ * <p>This method doesn't do anything if {@link #destroy()} was
+ * previously called.</p>
+ *
* @param canvas The Canvas previously returned by lockCanvas()
*
* @see #lockCanvas()
* @see #lockCanvas(android.graphics.Rect)
+ * @see #isDestroyed()
*/
public void unlockCanvasAndPost(Canvas canvas) {
- if (mCanvas != null && canvas == mCanvas) {
+ if (!mDestroyed && mCanvas != null && canvas == mCanvas) {
canvas.restoreToCount(mSaveCount);
mSaveCount = 0;
@@ -178,10 +197,39 @@ public class GraphicBuffer implements Parcelable {
}
}
+ /**
+ * Destroyes this buffer immediately. Calling this method frees up any
+ * underlying native resources. After calling this method, this buffer
+ * must not be used in any way ({@link #lockCanvas()} must not be called,
+ * etc.)
+ *
+ * @see #isDestroyed()
+ */
+ public void destroy() {
+ if (!mDestroyed) {
+ mDestroyed = true;
+ nDestroyGraphicBuffer(mNativeObject);
+ }
+ }
+
+ /**
+ * Indicates whether this buffer has been destroyed. A destroyed buffer
+ * cannot be used in any way: locking a Canvas will return null, the buffer
+ * cannot be written to a parcel, etc.
+ *
+ * @return True if this <code>GraphicBuffer</code> is in a destroyed state,
+ * false otherwise.
+ *
+ * @see #destroy()
+ */
+ public boolean isDestroyed() {
+ return mDestroyed;
+ }
+
@Override
protected void finalize() throws Throwable {
try {
- nDestroyGraphicBuffer(mNativeObject);
+ if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
} finally {
super.finalize();
}
@@ -192,8 +240,23 @@ public class GraphicBuffer implements Parcelable {
return 0;
}
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * <p>Calling this method will throw an <code>IllegalStateException</code> if
+ * {@link #destroy()} has been previously called.</p>
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
@Override
public void writeToParcel(Parcel dest, int flags) {
+ if (mDestroyed) {
+ throw new IllegalStateException("This GraphicBuffer has been destroyed and cannot be "
+ + "written to a parcel.");
+ }
+
dest.writeInt(mWidth);
dest.writeInt(mHeight);
dest.writeInt(mFormat);