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

Commit 2118b25a authored by Carl Shapiro's avatar Carl Shapiro
Browse files

Eliminate tracked allocations and the inNativeAlloc option.

Change-Id: Ic10b2b41a26925d799e5d1e50be77fc480ec0f17
parent 202ef9e8
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ jfieldID gOptions_configFieldID;
jfieldID gOptions_ditherFieldID;
jfieldID gOptions_purgeableFieldID;
jfieldID gOptions_shareableFieldID;
jfieldID gOptions_nativeAllocFieldID;
jfieldID gOptions_preferQualityOverSpeedFieldID;
jfieldID gOptions_widthFieldID;
jfieldID gOptions_heightFieldID;
@@ -155,12 +154,6 @@ static bool optionsJustBounds(JNIEnv* env, jobject options) {
            env->GetBooleanField(options, gOptions_justBoundsFieldID);
}

static bool optionsReportSizeToVM(JNIEnv* env, jobject options) {
    return NULL == options ||
            !env->GetBooleanField(options, gOptions_nativeAllocFieldID);
}


static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStream* stream,
                                   int sampleSize, bool ditherImage) {
    SkImageRef* pr;
@@ -188,7 +181,6 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
    bool doDither = true;
    bool isPurgeable = forcePurgeable ||
                        (allowPurgeable && optionsPurgeable(env, options));
    bool reportSizeToVM = optionsReportSizeToVM(env, options);
    bool preferQualityOverSpeed = false;
    jobject javaBitmap = NULL;
    
@@ -220,7 +212,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
    decoder->setPreferQualityOverSpeed(preferQualityOverSpeed);

    NinePatchPeeker     peeker(decoder);
    JavaPixelAllocator  javaAllocator(env, reportSizeToVM);
    JavaPixelAllocator  javaAllocator(env);
    SkBitmap*           bitmap;
    if (javaBitmap == NULL) {
        bitmap = new SkBitmap;
@@ -583,7 +575,6 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) {
    gOptions_ditherFieldID = getFieldIDCheck(env, gOptions_class, "inDither", "Z");
    gOptions_purgeableFieldID = getFieldIDCheck(env, gOptions_class, "inPurgeable", "Z");
    gOptions_shareableFieldID = getFieldIDCheck(env, gOptions_class, "inInputShareable", "Z");
    gOptions_nativeAllocFieldID = getFieldIDCheck(env, gOptions_class, "inNativeAlloc", "Z");
    gOptions_preferQualityOverSpeedFieldID = getFieldIDCheck(env, gOptions_class,
            "inPreferQualityOverSpeed", "Z");
    gOptions_widthFieldID = getFieldIDCheck(env, gOptions_class, "outWidth", "I");
+0 −3
Original line number Diff line number Diff line
@@ -81,10 +81,7 @@ static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream) {

    JavaPixelAllocator *javaAllocator = new JavaPixelAllocator(env);
    decoder->setAllocator(javaAllocator);
    JavaMemoryUsageReporter *javaMemoryReporter = new JavaMemoryUsageReporter(env);
    decoder->setReporter(javaMemoryReporter);
    javaAllocator->unref();
    javaMemoryReporter->unref();

    if (!decoder->buildTileIndex(stream, &width, &height)) {
        char msg[100];
+5 −98
Original line number Diff line number Diff line
@@ -9,9 +9,6 @@
#include "SkRegion.h"
#include <android_runtime/AndroidRuntime.h>

//#define REPORT_SIZE_TO_JVM
//#define TRACK_LOCK_COUNT

void doThrow(JNIEnv* env, const char* exc, const char* msg) {
    // don't throw a new exception if we already have one pending
    if (env->ExceptionCheck() == JNI_FALSE) {
@@ -186,10 +183,6 @@ static jclass gRegion_class;
static jfieldID gRegion_nativeInstanceID;
static jmethodID gRegion_constructorMethodID;

static jobject   gVMRuntime_singleton;
static jmethodID gVMRuntime_trackExternalAllocationMethodID;
static jmethodID gVMRuntime_trackExternalFreeMethodID;

///////////////////////////////////////////////////////////////////////////////

void GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
@@ -428,10 +421,6 @@ static JNIEnv* vm2env(JavaVM* vm)
    return env;
}

#ifdef TRACK_LOCK_COUNT
    static int gLockCount;
#endif

///////////////////////////////////////////////////////////////////////////////

AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
@@ -539,36 +528,10 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
    return arrayObj;
}

bool GraphicsJNI::mallocPixelRef(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable) {
    Sk64 size64 = bitmap->getSize64();
    if (size64.isNeg() || !size64.is32()) {
        doThrow(env, "java/lang/IllegalArgumentException",
                     "bitmap size exceeds 32bits");
        return false;
    }

    size_t size = size64.get32();

    // call the version of malloc that returns null on failure
    void* addr = sk_malloc_flags(size, 0);

    if (NULL == addr) {
        return false;
    }

    SkPixelRef* pr = new AndroidPixelRef(env, addr, size, NULL, ctable);
    bitmap->setPixelRef(pr)->unref();
    // since we're already allocated, we lockPixels right away
    // HeapAllocator behaves this way too
    bitmap->lockPixels();
    return true;
}

///////////////////////////////////////////////////////////////////////////////

JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env, bool allocateInJavaHeap)
    : fAllocateInJavaHeap(allocateInJavaHeap),
      fStorageObj(NULL),
JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env)
    : fStorageObj(NULL),
      fAllocCount(0) {
    if (env->GetJavaVM(&fVM) != JNI_OK) {
        SkDebugf("------ [%p] env->GetJavaVM failed\n", env);
@@ -585,50 +548,10 @@ bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
        SkDebugf("WARNING: One-shot allocator has already allocated (alloc count = %d)\n", fAllocCount);
//        sk_throw();
    }

    if (fAllocateInJavaHeap) {
    fStorageObj = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
    fAllocCount += 1;
    return fStorageObj != NULL;
}
    return GraphicsJNI::mallocPixelRef(env, bitmap, ctable);
}

////////////////////////////////////////////////////////////////////////////////

JavaMemoryUsageReporter::JavaMemoryUsageReporter(JNIEnv* env)
    : fTotalSize(0) {
    if (env->GetJavaVM(&fVM) != JNI_OK) {
        SkDebugf("------ [%p] env->GetJavaVM failed\n", env);
        sk_throw();
    }
}

JavaMemoryUsageReporter::~JavaMemoryUsageReporter() {
    JNIEnv* env = vm2env(fVM);
    jlong jtotalSize = fTotalSize;
    env->CallVoidMethod(gVMRuntime_singleton,
            gVMRuntime_trackExternalFreeMethodID,
            jtotalSize);
}

bool JavaMemoryUsageReporter::reportMemory(size_t memorySize) {
    jlong jsize = memorySize;  // the VM wants longs for the size
    JNIEnv* env = vm2env(fVM);
    bool r = env->CallBooleanMethod(gVMRuntime_singleton,
            gVMRuntime_trackExternalAllocationMethodID,
            jsize);
    if (GraphicsJNI::hasException(env)) {
        return false;
    }
    if (!r) {
        LOGE("VM won't let us allocate %zd bytes\n", memorySize);
        doThrowOOME(env, "bitmap size exceeds VM budget");
        return false;
    }
    fTotalSize += memorySize;
    return true;
}

////////////////////////////////////////////////////////////////////////////////

@@ -716,21 +639,5 @@ int register_android_graphics_Graphics(JNIEnv* env)
    gRegion_constructorMethodID = env->GetMethodID(gRegion_class, "<init>",
        "(II)V");
    
    // Get the VMRuntime class.
    c = env->FindClass("dalvik/system/VMRuntime");
    SkASSERT(c);
    // Look up VMRuntime.getRuntime().
    m = env->GetStaticMethodID(c, "getRuntime", "()Ldalvik/system/VMRuntime;");
    SkASSERT(m);
    // Call VMRuntime.getRuntime() and hold onto its result.
    gVMRuntime_singleton = env->CallStaticObjectMethod(c, m);
    SkASSERT(gVMRuntime_singleton);
    gVMRuntime_singleton = (jobject)env->NewGlobalRef(gVMRuntime_singleton);
    // Look up the VMRuntime methods we'll be using.
    gVMRuntime_trackExternalAllocationMethodID =
                        env->GetMethodID(c, "trackExternalAllocation", "(J)Z");
    gVMRuntime_trackExternalFreeMethodID =
                            env->GetMethodID(c, "trackExternalFree", "(J)V");

    return 0;
}
+0 −18
Original line number Diff line number Diff line
@@ -65,12 +65,6 @@ public:
    static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
                                     SkColorTable* ctable);

    /** Set a pixelref for the bitmap (needs setConfig to already be called)
        Returns true on success. If it returns false, then it failed, and the
        appropriate exception will have been raised.
    */
    static bool mallocPixelRef(JNIEnv*, SkBitmap*, SkColorTable* ctable);

    /** Copy the colors in colors[] to the bitmap, convert to the correct
        format along the way.
    */
@@ -169,18 +163,6 @@ private:
    int fAllocCount;
};

class JavaMemoryUsageReporter : public SkVMMemoryReporter {
public:
    JavaMemoryUsageReporter(JNIEnv* env);
    virtual ~JavaMemoryUsageReporter();
    // overrides
    virtual bool reportMemory(size_t memorySize);

private:
    JavaVM* fVM;
    size_t fTotalSize;
};

enum JNIAccess {
    kRO_JNIAccess,
    kRW_JNIAccess
+0 −13
Original line number Diff line number Diff line
@@ -212,19 +212,6 @@ public class BitmapFactory {
         */
        public boolean inInputShareable;

        /**
         * Normally bitmap allocations count against the dalvik heap, which
         * means they help trigger GCs when a lot have been allocated. However,
         * in rare cases, the caller may want to allocate the bitmap outside of
         * that heap. To request that, set inNativeAlloc to true. In these
         * rare instances, it is solely up to the caller to ensure that OOM is
         * managed explicitly by calling bitmap.recycle() as soon as such a
         * bitmap is no longer needed.
         *
         * @hide pending API council approval
         */
        public boolean inNativeAlloc;

        /**
         * If inPreferQualityOverSpeed is set to true, the decoder will try to
         * decode the reconstructed image to a higher quality even at the