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

Commit d5e27e32 authored by Carl Shapiro's avatar Carl Shapiro Committed by Android (Google) Code Review
Browse files

Merge "Eliminate tracked allocations and the inNativeAlloc option."

parents ae115191 2118b25a
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