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

Commit bbdb7312 authored by Leon Scroggins III's avatar Leon Scroggins III Committed by Leon Scroggins
Browse files

Stop double-counting native memory in graphics classes

Bug: 121304803
Test: Infeasible

Previously, the NativeAllocationRegistry needed to report how much
native memory was being held onto by the Java class in order to get a
more accurate count of how much memory was in use. But recent changes
allow the system to have an even more accurate view of the native memory
with mallinfo(). Further, the AOSP change
Idccb8b50d26c8c3e93cc34040d784f74dfcdbf51 introduces new APIs that allow
distinguishing between large native malloc allocations, which should
cause more frequent mallinfo() checks, and whose sizes need be available
to ahat etc, and smaller native malloc allocations.

Bitmap and AnimatedImageDrawable use the version for large native malloc
allocations. The rest pass an implied size of 0. Note that many of the
old Registries used somewhat arbitrary sizes, reinforcing the fact that
the new way of keeping track of this is better.

Add Bitmap::pixelStorageType to differentiate between types of memory
that should be accounted for by the Registry.

Update Bitmap::getAllocationByteCount to report the actual size of
ashmem allocation.

Fix a typo in LineBreaker.java, discovered while looking to find
existing callers of Bitmap's constructor.

Change-Id: I57c407258450aeaf08b47df32432466639d9faed
parent 309eb41a
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -206,13 +206,14 @@ jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
    // The caller needs to have already set the alpha type properly, so the
    // native SkBitmap stays in sync with the Java Bitmap.
    assert_premultiplied(bitmap->info(), isPremultiplied);
    bool fromMalloc = bitmap->pixelStorageType() == PixelStorageType::Heap;
    BitmapWrapper* bitmapWrapper = new BitmapWrapper(bitmap);
    if (!isMutable) {
        bitmapWrapper->bitmap().setImmutable();
    }
    jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
            reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density,
            isPremultiplied, ninePatchChunk, ninePatchInsets);
            isPremultiplied, ninePatchChunk, ninePatchInsets, fromMalloc);

    if (env->ExceptionCheck() != 0) {
        ALOGE("*** Uncaught exception returned from Java call!\n");
@@ -1224,7 +1225,7 @@ int register_android_graphics_Bitmap(JNIEnv* env)
{
    gBitmap_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Bitmap"));
    gBitmap_nativePtr = GetFieldIDOrDie(env, gBitmap_class, "mNativePtr", "J");
    gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;)V");
    gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
    gBitmap_reinitMethodID = GetMethodIDOrDie(env, gBitmap_class, "reinit", "(IIZ)V");
    gBitmap_getAllocationByteCountMethodID = GetMethodIDOrDie(env, gBitmap_class, "getAllocationByteCount", "()I");
    return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods,
+25 −8
Original line number Diff line number Diff line
@@ -122,13 +122,22 @@ public final class Bitmap implements Parcelable {
    }

    /**
     * Private constructor that must received an already allocated native bitmap
     * Private constructor that must receive an already allocated native bitmap
     * int (pointer).
     */
    // called from JNI
    @UnsupportedAppUsage
    Bitmap(long nativeBitmap, int width, int height, int density, boolean requestPremultiplied,
            byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) {
    // JNI now calls the version below this one. This is preserved due to UnsupportedAppUsage.
    @UnsupportedAppUsage(maxTargetSdk = 28)
    Bitmap(long nativeBitmap, int width, int height, int density,
            boolean requestPremultiplied, byte[] ninePatchChunk,
            NinePatch.InsetStruct ninePatchInsets) {
        this(nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk,
                ninePatchInsets, true);
    }

    // called from JNI and Bitmap_Delegate.
    Bitmap(long nativeBitmap, int width, int height, int density,
            boolean requestPremultiplied, byte[] ninePatchChunk,
            NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) {
        if (nativeBitmap == 0) {
            throw new RuntimeException("internal error: native bitmap is 0");
        }
@@ -144,13 +153,21 @@ public final class Bitmap implements Parcelable {
        }

        mNativePtr = nativeBitmap;
        long nativeSize = NATIVE_ALLOCATION_SIZE + getAllocationByteCount();
        NativeAllocationRegistry registry = new NativeAllocationRegistry(
            Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), nativeSize);

        final int allocationByteCount = getAllocationByteCount();
        NativeAllocationRegistry registry;
        if (fromMalloc) {
            registry = NativeAllocationRegistry.createMalloced(
                    Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount);
        } else {
            registry = NativeAllocationRegistry.createNonmalloced(
                    Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount);
        }
        registry.registerNativeAllocation(this, nativeBitmap);

        if (ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD) {
            sPreloadTracingNumInstantiatedBitmaps++;
            long nativeSize = NATIVE_ALLOCATION_SIZE + allocationByteCount;
            sPreloadTracingTotalBitmapsSize += nativeSize;
        }
    }
+3 −6
Original line number Diff line number Diff line
@@ -76,14 +76,11 @@ public class Canvas extends BaseCanvas {
    // (see SkCanvas.cpp, SkDraw.cpp)
    private static final int MAXMIMUM_BITMAP_SIZE = 32766;

    // The approximate size of the native allocation associated with
    // a Canvas object.
    private static final long NATIVE_ALLOCATION_SIZE = 525;

    // Use a Holder to allow static initialization of Canvas in the boot image.
    private static class NoImagePreloadHolder {
        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
                Canvas.class.getClassLoader(), nGetNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
        public static final NativeAllocationRegistry sRegistry =
                NativeAllocationRegistry.createMalloced(
                Canvas.class.getClassLoader(), nGetNativeFinalizer());
    }

    // This field is used to finalize the native Canvas properly
+3 −2
Original line number Diff line number Diff line
@@ -26,8 +26,9 @@ import libcore.util.NativeAllocationRegistry;
public class ColorFilter {

    private static class NoImagePreloadHolder {
        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
                ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50);
        public static final NativeAllocationRegistry sRegistry =
                NativeAllocationRegistry.createMalloced(
                ColorFilter.class.getClassLoader(), nativeGetFinalizer());
    }

    /**
+6 −4
Original line number Diff line number Diff line
@@ -44,13 +44,15 @@ public class FontFamily {

    private static String TAG = "FontFamily";

    private static final NativeAllocationRegistry sBuilderRegistry = new NativeAllocationRegistry(
            FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc(), 64);
    private static final NativeAllocationRegistry sBuilderRegistry =
            NativeAllocationRegistry.createMalloced(
            FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc());

    private @Nullable Runnable mNativeBuilderCleaner;

    private static final NativeAllocationRegistry sFamilyRegistry = new NativeAllocationRegistry(
            FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc(), 64);
    private static final NativeAllocationRegistry sFamilyRegistry =
            NativeAllocationRegistry.createMalloced(
            FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc());

    /**
     * @hide
Loading