Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f1fd8c2 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Track native metadata allocations

Native camera metadata buffers can increase both in size
and count over prolonged periods of camera usage.
Register and track the native buffer allocation in the Java
VM to improve GC.

Bug: 168100424
Bug: 170243539
Test: Camera CTS
Change-Id: I7a10c2f360307a6c1afeecde24dc42184106b872
parent b914950d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ import android.util.Range;
import android.util.Size;

import dalvik.annotation.optimization.FastNative;
import dalvik.system.VMRuntime;

import java.io.IOException;
import java.nio.ByteBuffer;
@@ -351,6 +352,7 @@ public class CameraMetadataNative implements Parcelable {
        if (mMetadataPtr == 0) {
            throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
        }
        updateNativeAllocation();
    }

    /**
@@ -362,6 +364,7 @@ public class CameraMetadataNative implements Parcelable {
        if (mMetadataPtr == 0) {
            throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
        }
        updateNativeAllocation();
    }

    /**
@@ -443,6 +446,7 @@ public class CameraMetadataNative implements Parcelable {

    public void readFromParcel(Parcel in) {
        nativeReadFromParcel(in, mMetadataPtr);
        updateNativeAllocation();
    }

    /**
@@ -533,6 +537,11 @@ public class CameraMetadataNative implements Parcelable {
        // Delete native pointer, but does not clear it
        nativeClose(mMetadataPtr);
        mMetadataPtr = 0;

        if (mBufferSize > 0) {
            VMRuntime.getRuntime().registerNativeFree(mBufferSize);
        }
        mBufferSize = 0;
    }

    private <T> T getBase(CameraCharacteristics.Key<T> key) {
@@ -1645,9 +1654,26 @@ public class CameraMetadataNative implements Parcelable {
        return true;
    }

    private void updateNativeAllocation() {
        long currentBufferSize = nativeGetBufferSize(mMetadataPtr);

        if (currentBufferSize != mBufferSize) {
            if (mBufferSize > 0) {
                VMRuntime.getRuntime().registerNativeFree(mBufferSize);
            }

            mBufferSize = currentBufferSize;

            if (mBufferSize > 0) {
                VMRuntime.getRuntime().registerNativeAllocation(mBufferSize);
            }
        }
    }

    private int mCameraId = -1;
    private boolean mHasMandatoryConcurrentStreams = false;
    private Size mDisplaySize = new Size(0, 0);
    private long mBufferSize = 0;

    /**
     * Set the current camera Id.
@@ -1705,6 +1731,8 @@ public class CameraMetadataNative implements Parcelable {
    private static synchronized native boolean nativeIsEmpty(long ptr);
    @FastNative
    private static synchronized native int nativeGetEntryCount(long ptr);
    @FastNative
    private static synchronized native long nativeGetBufferSize(long ptr);

    @UnsupportedAppUsage
    @FastNative
@@ -1744,6 +1772,8 @@ public class CameraMetadataNative implements Parcelable {
        mCameraId = other.mCameraId;
        mHasMandatoryConcurrentStreams = other.mHasMandatoryConcurrentStreams;
        mDisplaySize = other.mDisplaySize;
        updateNativeAllocation();
        other.updateNativeAllocation();
    }

    /**
+13 −0
Original line number Diff line number Diff line
@@ -249,6 +249,16 @@ static jint CameraMetadata_getEntryCount(JNIEnv *env, jclass thiz, jlong ptr) {
    return metadata->entryCount();
}

static jlong CameraMetadata_getBufferSize(JNIEnv *env, jclass thiz, jlong ptr) {
    ALOGV("%s", __FUNCTION__);

    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, ptr);

    if (metadata == NULL) return 0;

    return metadata->bufferSize();
}

// idempotent. calling more than once has no effect.
static void CameraMetadata_close(JNIEnv *env, jclass thiz, jlong ptr) {
    ALOGV("%s", __FUNCTION__);
@@ -552,6 +562,9 @@ static const JNINativeMethod gCameraMetadataMethods[] = {
  { "nativeGetEntryCount",
    "(J)I",
    (void*)CameraMetadata_getEntryCount },
  { "nativeGetBufferSize",
    "(J)J",
    (void*)CameraMetadata_getBufferSize },
  { "nativeClose",
    "(J)V",
    (void*)CameraMetadata_close },