Use buffer size for NativeAllocationRegistry instead of a fixed value
When calling NativeAllocationRegistry for HardwareBuffer, it needs the
correct size so GC knows how much memory has been allocated and when to
run. The current behavior uses a fixed size so it's likely the buffer is
actually consuming more memory than what GC thinks.
Test: atest ContentCapturePerfTests:LoginTest
Bug: 168149157
Bug: 168154840
Change-Id: Ife174478b2b76214b438de2757289a973330c979
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index dd34930..a9b6132 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -26,6 +26,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
import dalvik.system.CloseGuard;
@@ -141,8 +142,6 @@
/** Usage: The buffer contains a complete mipmap hierarchy */
public static final long USAGE_GPU_MIPMAP_COMPLETE = 1 << 26;
- // The approximate size of a native AHardwareBuffer object.
- private static final long NATIVE_HARDWARE_BUFFER_SIZE = 232;
/**
* Creates a new <code>HardwareBuffer</code> instance.
*
@@ -239,10 +238,10 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private HardwareBuffer(long nativeObject) {
mNativeObject = nativeObject;
-
+ long bufferSize = nEstimateSize(nativeObject);
ClassLoader loader = HardwareBuffer.class.getClassLoader();
NativeAllocationRegistry registry = new NativeAllocationRegistry(
- loader, nGetNativeFinalizer(), NATIVE_HARDWARE_BUFFER_SIZE);
+ loader, nGetNativeFinalizer(), bufferSize);
mCleaner = registry.registerNativeAllocation(this, mNativeObject);
mCloseGuard.open("close");
}
@@ -429,4 +428,6 @@
private static native long nGetUsage(long nativeObject);
private static native boolean nIsSupported(int width, int height, int format, int layers,
long usage);
+ @CriticalNative
+ private static native long nEstimateSize(long nativeObject);
}
diff --git a/core/jni/android_hardware_HardwareBuffer.cpp b/core/jni/android_hardware_HardwareBuffer.cpp
index e78e08e..2944f72 100644
--- a/core/jni/android_hardware_HardwareBuffer.cpp
+++ b/core/jni/android_hardware_HardwareBuffer.cpp
@@ -30,8 +30,9 @@
#include <binder/Parcel.h>
-#include <ui/GraphicBuffer.h>
#include <private/gui/ComposerService.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
#include <hardware/gralloc1.h>
#include <grallocusage/GrallocUsageConversion.h>
@@ -166,6 +167,20 @@
return AHardwareBuffer_convertFromGrallocUsageBits(buffer->getUsage());
}
+static jlong android_hardware_HardwareBuffer_estimateSize(jlong nativeObject) {
+ GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject);
+
+ uint32_t bpp = bytesPerPixel(buffer->getPixelFormat());
+ if (bpp == 0) {
+ // If the pixel format is not recognized, use 1 as default.
+ bpp = 1;
+ }
+
+ const uint32_t bufferStride =
+ buffer->getStride() > 0 ? buffer->getStride() : buffer->getWidth();
+ return static_cast<jlong>(buffer->getHeight() * bufferStride * bpp);
+}
+
// ----------------------------------------------------------------------------
// Serialization
// ----------------------------------------------------------------------------
@@ -247,6 +262,7 @@
const char* const kClassPathName = "android/hardware/HardwareBuffer";
+// clang-format off
static const JNINativeMethod gMethods[] = {
{ "nCreateHardwareBuffer", "(IIIIJ)J",
(void*) android_hardware_HardwareBuffer_create },
@@ -267,7 +283,11 @@
{ "nGetFormat", "(J)I", (void*) android_hardware_HardwareBuffer_getFormat },
{ "nGetLayers", "(J)I", (void*) android_hardware_HardwareBuffer_getLayers },
{ "nGetUsage", "(J)J", (void*) android_hardware_HardwareBuffer_getUsage },
+
+ // --------------- @CriticalNative ----------------------
+ { "nEstimateSize", "(J)J", (void*) android_hardware_HardwareBuffer_estimateSize },
};
+// clang-format on
int register_android_hardware_HardwareBuffer(JNIEnv* env) {
int err = RegisterMethodsOrDie(env, kClassPathName, gMethods,