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

Commit 5e49b497 authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

Update framework to use M33 Skia. DO NOT MERGE

(These CLs are already in master.)

Bug: 13246311

This cherry-picks 7 CLs:

-----------------------------------------------------------------------

Remove calls to deprecated SkBitmap::setIsOpaque()

setIsOpaque() has been removed from ToT Skia.

Update setters for mIsPremultiplied and hasAlpha to take the
other into consideration.

cherry-pick from: I1b36b0b0ce7126031eb7b769b563c17dcd4b306a

-----------------------------------------------------------------------

Merge AssetStream with AssetStreamAdaptor.

Add enums to the constructor for AssetStreamAdaptor to choose the
different behaviors used by the (former) two different classes.

The old clients of AssetStream now get the following features of
AssetStreamAdaptor
- Debugging statements on error.
- The stream is an SkStreamRewindable.
- getLength() returns the correct value, and the old way of getting
  the length (read(NULL, 0)) is no longer implemented, since it is
  no longer used.
- isAtEnd() returns the correct value. ToT Skia makes it pure virtual,
  so some implementation is necessary.

cherry-pick from: I2a5395914e4f53830aaefee396556459083a1c56

-----------------------------------------------------------------------

Deprecate Android-specific SkPaint functions.

The following functions were problematic:
 const SkGlyph& getUnicharMetrics(SkUnichar, const SkMatrix*);
 const SkGlyph& getGlyphMetrics(uint16_t, const SkMatrix*);
 const void* findImage(const SkGlyph&, const SkMatrix*);

Replacing them with calls through SkGlyphCache solved a nasty crash
bug, so they have all been deprecated.

Bug: 11968757
cherry-pick from: Id746315d41aec5b211b78b172a883c2061130f08

-----------------------------------------------------------------------

pass SkGlyphCache into updateGlyphCache()

Doing so prevents us from double-locking the glyph cache, thereby
effectively locking ourselves out of reusing work that we'd just done.

Bug: 11968757
cherry-pick from: I5c552f2d0bbe30af2ce9054ba684e7da756a0d89

-----------------------------------------------------------------------

Updates to the Skia API needed to merge the WebView m33 version of Skia.

cherry-pick from: I0f63b53f2aae58871413b132742fc84138f069a3

Bugfix for screenshots (recent apps) due to incorrect rowBytes computation

bug: 12915192
cherry-pick from: I4d5fe2a2f75baf66099e0970fb646686a1992714

-----------------------------------------------------------------------

Fix bug in AndroidPixelRef where we did not store the correct imageInfo for a recycled bitmap.

cherry-pick from: I882483b78886e2f19fa4e43a86e69f5a82b3b7e5

-----------------------------------------------------------------------

Change-Id: Ie2b731a9f0795802418cfecddb4b684c92c64d33
parent 77a60f00
Loading
Loading
Loading
Loading
+15 −9
Original line number Original line Diff line number Diff line
@@ -227,7 +227,7 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
    do {
    do {
        *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
        *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
    } while (--width != 0);
    } while (--width != 0);
    ctable->unlockColors(false);
    ctable->unlockColors();
}
}


static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
@@ -240,7 +240,7 @@ static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
                                SkGetPackedG32(c), SkGetPackedB32(c));
                                SkGetPackedG32(c), SkGetPackedB32(c));
    } while (--width != 0);
    } while (--width != 0);
    ctable->unlockColors(false);
    ctable->unlockColors();
}
}


static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
@@ -253,7 +253,7 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
                               SkGetPackedB32(c));
                               SkGetPackedB32(c));
    } while (--width != 0);
    } while (--width != 0);
    ctable->unlockColors(false);
    ctable->unlockColors();
}
}


// can return NULL
// can return NULL
@@ -442,9 +442,15 @@ static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap) {
    return !bitmap->isOpaque();
    return !bitmap->isOpaque();
}
}


static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap,
static void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, SkBitmap* bitmap,
                               jboolean hasAlpha) {
                                            jboolean hasAlpha, jboolean isPremul) {
    bitmap->setIsOpaque(!hasAlpha);
    if (!hasAlpha) {
        bitmap->setAlphaType(kOpaque_SkAlphaType);
    } else if (isPremul) {
        bitmap->setAlphaType(kPremul_SkAlphaType);
    } else {
        bitmap->setAlphaType(kUnpremul_SkAlphaType);
    }
}
}


static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
@@ -543,14 +549,14 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
    p->writeInt32(bitmap->rowBytes());
    p->writeInt32(bitmap->rowBytes());
    p->writeInt32(density);
    p->writeInt32(density);


    if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
    if (bitmap->config() == SkBitmap::kIndex8_Config) {
        SkColorTable* ctable = bitmap->getColorTable();
        SkColorTable* ctable = bitmap->getColorTable();
        if (ctable != NULL) {
        if (ctable != NULL) {
            int count = ctable->count();
            int count = ctable->count();
            p->writeInt32(count);
            p->writeInt32(count);
            memcpy(p->writeInplace(count * sizeof(SkPMColor)),
            memcpy(p->writeInplace(count * sizeof(SkPMColor)),
                   ctable->lockColors(), count * sizeof(SkPMColor));
                   ctable->lockColors(), count * sizeof(SkPMColor));
            ctable->unlockColors(false);
            ctable->unlockColors();
        } else {
        } else {
            p->writeInt32(0);   // indicate no ctable
            p->writeInt32(0);   // indicate no ctable
        }
        }
@@ -770,7 +776,7 @@ static JNINativeMethod gBitmapMethods[] = {
    {   "nativeRowBytes",           "(I)I", (void*)Bitmap_rowBytes },
    {   "nativeRowBytes",           "(I)I", (void*)Bitmap_rowBytes },
    {   "nativeConfig",             "(I)I", (void*)Bitmap_config },
    {   "nativeConfig",             "(I)I", (void*)Bitmap_config },
    {   "nativeHasAlpha",           "(I)Z", (void*)Bitmap_hasAlpha },
    {   "nativeHasAlpha",           "(I)Z", (void*)Bitmap_hasAlpha },
    {   "nativeSetHasAlpha",        "(IZ)V", (void*)Bitmap_setHasAlpha },
    {   "nativeSetAlphaAndPremultiplied", "(IZZ)V", (void*)Bitmap_setAlphaAndPremultiplied},
    {   "nativeHasMipMap",          "(I)Z", (void*)Bitmap_hasMipMap },
    {   "nativeHasMipMap",          "(I)Z", (void*)Bitmap_hasMipMap },
    {   "nativeSetHasMipMap",       "(IZ)V", (void*)Bitmap_setHasMipMap },
    {   "nativeSetHasMipMap",       "(IZ)V", (void*)Bitmap_setHasMipMap },
    {   "nativeCreateFromParcel",
    {   "nativeCreateFromParcel",
+26 −8
Original line number Original line Diff line number Diff line
@@ -124,12 +124,18 @@ static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) {
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
        int sampleSize, bool ditherImage) {
        int sampleSize, bool ditherImage) {


    SkImageInfo bitmapInfo;
    if (!bitmap->asImageInfo(&bitmapInfo)) {
        ALOGW("bitmap has unknown configuration so no memory has been allocated");
        return NULL;
    }

    SkImageRef* pr;
    SkImageRef* pr;
    // only use ashmem for large images, since mmaps come at a price
    // only use ashmem for large images, since mmaps come at a price
    if (bitmap->getSize() >= 32 * 1024) {
    if (bitmap->getSize() >= 32 * 1024) {
        pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize);
        pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize);
    } else {
    } else {
        pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize);
        pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize);
    }
    }
    pr->setDitherImage(ditherImage);
    pr->setDitherImage(ditherImage);
    bitmap->setPixelRef(pr)->unref();
    bitmap->setPixelRef(pr)->unref();
@@ -157,7 +163,7 @@ public:
    virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
    virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
        // accounts for scale in final allocation, using eventual size and config
        // accounts for scale in final allocation, using eventual size and config
        const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
        const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
                configForScaledOutput(bitmap->getConfig()));
                configForScaledOutput(bitmap->config()));
        const int requestedSize = bytesPerPixel *
        const int requestedSize = bytesPerPixel *
                int(bitmap->width() * mScale + 0.5f) *
                int(bitmap->width() * mScale + 0.5f) *
                int(bitmap->height() * mScale + 0.5f);
                int(bitmap->height() * mScale + 0.5f);
@@ -191,8 +197,15 @@ public:
            return false;
            return false;
        }
        }


        SkImageInfo bitmapInfo;
        if (!bitmap->asImageInfo(&bitmapInfo)) {
            ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
            return false;
        }

        // Create a new pixelref with the new ctable that wraps the previous pixelref
        // Create a new pixelref with the new ctable that wraps the previous pixelref
        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable);
        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef),
                bitmapInfo, bitmap->rowBytes(), ctable);


        bitmap->setPixelRef(pr)->unref();
        bitmap->setPixelRef(pr)->unref();
        // since we're already allocated, we lockPixels right away
        // since we're already allocated, we lockPixels right away
@@ -401,8 +414,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding


        // TODO: avoid copying when scaled size equals decodingBitmap size
        // TODO: avoid copying when scaled size equals decodingBitmap size
        SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
        SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
        outputBitmap->setConfig(config, scaledWidth, scaledHeight);
        // FIXME: If the alphaType is kUnpremul and the image has alpha, the
        outputBitmap->setIsOpaque(decodingBitmap.isOpaque());
        // colors may not be correct, since Skia does not yet support drawing
        // to/from unpremultiplied bitmaps.
        outputBitmap->setConfig(config, scaledWidth, scaledHeight, 0,
                                decodingBitmap.alphaType());
        if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
        if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
            return nullObjectReturn("allocation failed for scaled bitmap");
            return nullObjectReturn("allocation failed for scaled bitmap");
        }
        }
@@ -414,7 +430,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
        }
        }


        SkPaint paint;
        SkPaint paint;
        paint.setFilterBitmap(true);
        paint.setFilterLevel(SkPaint::kLow_FilterLevel);


        SkCanvas canvas(*outputBitmap);
        SkCanvas canvas(*outputBitmap);
        canvas.scale(sx, sy);
        canvas.scale(sx, sy);
@@ -541,7 +557,9 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset,
    } else {
    } else {
        // since we know we'll be done with the asset when we return, we can
        // since we know we'll be done with the asset when we return, we can
        // just use a simple wrapper
        // just use a simple wrapper
        stream = new AssetStreamAdaptor(asset);
        stream = new AssetStreamAdaptor(asset,
                                        AssetStreamAdaptor::kNo_OwnAsset,
                                        AssetStreamAdaptor::kNo_HasMemoryBase);
    }
    }
    SkAutoUnref aur(stream);
    SkAutoUnref aur(stream);
    return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
    return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
+4 −5
Original line number Original line Diff line number Diff line
@@ -29,7 +29,6 @@
#include "CreateJavaOutputStreamAdaptor.h"
#include "CreateJavaOutputStreamAdaptor.h"
#include "Utils.h"
#include "Utils.h"
#include "JNIHelp.h"
#include "JNIHelp.h"
#include "SkTScopedPtr.h"


#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/AndroidRuntime.h>
#include "android_util_Binder.h"
#include "android_util_Binder.h"
@@ -76,7 +75,7 @@ private:
    int fHeight;
    int fHeight;
};
};


static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) {
static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) {
    SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
    SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
    int width, height;
    int width, height;
    if (NULL == decoder) {
    if (NULL == decoder) {
@@ -108,7 +107,7 @@ static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray b
        For now we just always copy the array's data if isShareable.
        For now we just always copy the array's data if isShareable.
     */
     */
    AutoJavaByteArray ar(env, byteArray);
    AutoJavaByteArray ar(env, byteArray);
    SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
    SkStreamRewindable* stream = new SkMemoryStream(ar.ptr() + offset, length, true);


    jobject brd = createBitmapRegionDecoder(env, stream);
    jobject brd = createBitmapRegionDecoder(env, stream);
    SkSafeUnref(stream); // the decoder now holds a reference
    SkSafeUnref(stream); // the decoder now holds a reference
@@ -215,7 +214,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b
    region.fRight = start_x + width;
    region.fRight = start_x + width;
    region.fBottom = start_y + height;
    region.fBottom = start_y + height;
    SkBitmap* bitmap = NULL;
    SkBitmap* bitmap = NULL;
    SkTScopedPtr<SkBitmap> adb;
    SkAutoTDelete<SkBitmap> adb;


    if (tileBitmap != NULL) {
    if (tileBitmap != NULL) {
        // Re-use bitmap.
        // Re-use bitmap.
@@ -246,7 +245,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b
    }
    }


    // detach bitmap from its autodeleter, since we want to own it now
    // detach bitmap from its autodeleter, since we want to own it now
    adb.release();
    adb.detach();


    JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
    JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
    jbyteArray buff = allocator->getStorageObjAndReset();
    jbyteArray buff = allocator->getStorageObjAndReset();
+3 −3
Original line number Original line Diff line number Diff line
@@ -476,7 +476,7 @@ public:
                if (paint) {
                if (paint) {
                    filteredPaint = *paint;
                    filteredPaint = *paint;
                }
                }
                filteredPaint.setFilterBitmap(true);
                filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
                canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
                canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
            } else {
            } else {
                canvas->drawBitmap(*bitmap, left_, top_, paint);
                canvas->drawBitmap(*bitmap, left_, top_, paint);
@@ -491,7 +491,7 @@ public:
            if (paint) {
            if (paint) {
                filteredPaint = *paint;
                filteredPaint = *paint;
            }
            }
            filteredPaint.setFilterBitmap(true);
            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);


            canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
            canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);


@@ -514,7 +514,7 @@ public:
            if (paint) {
            if (paint) {
                filteredPaint = *paint;
                filteredPaint = *paint;
            }
            }
            filteredPaint.setFilterBitmap(true);
            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
            canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
            canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
        } else {
        } else {
            canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
            canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+36 −7
Original line number Original line Diff line number Diff line
@@ -346,6 +346,18 @@ SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)


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


// Assert that bitmap's SkAlphaType is consistent with isPremultiplied.
static void assert_premultiplied(const SkBitmap& bitmap, bool isPremultiplied) {
    // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is
    // irrelevant. This just tests to ensure that the SkAlphaType is not
    // opposite of isPremultiplied.
    if (isPremultiplied) {
        SkASSERT(bitmap.alphaType() != kUnpremul_SkAlphaType);
    } else {
        SkASSERT(bitmap.alphaType() != kPremul_SkAlphaType);
    }
}

jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
        int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
        int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
{
{
@@ -354,6 +366,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buff
    bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
    bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
    bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
    bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;


    // 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, isPremultiplied);

    jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
    jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
            static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer,
            static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer,
            bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
            bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
@@ -371,6 +387,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreat
void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
        bool isPremultiplied)
        bool isPremultiplied)
{
{
    // 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, isPremultiplied);

    env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
    env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
            bitmap->width(), bitmap->height(), isPremultiplied);
            bitmap->width(), bitmap->height(), isPremultiplied);
}
}
@@ -413,8 +433,9 @@ static JNIEnv* vm2env(JavaVM* vm)


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


AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage,
        SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
        size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) :
        SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
        fWrappedPixelRef(NULL) {
        fWrappedPixelRef(NULL) {
    SkASSERT(storage);
    SkASSERT(storage);
    SkASSERT(env);
    SkASSERT(env);
@@ -429,11 +450,11 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteA


    // If storageObj is NULL, the memory was NOT allocated on the Java heap
    // If storageObj is NULL, the memory was NOT allocated on the Java heap
    fOnJavaHeap = (storageObj != NULL);
    fOnJavaHeap = (storageObj != NULL);

}
}


AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
        SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
        size_t rowBytes, SkColorTable* ctable) :
        SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false),
        fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
        fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
                wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
                wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
{
{
@@ -540,13 +561,21 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
        return NULL;
        return NULL;
    }
    }


    SkImageInfo bitmapInfo;
    if (!bitmap->asImageInfo(&bitmapInfo)) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                "unknown bitmap configuration");
        return NULL;
    }

    size_t size = size64.get32();
    size_t size = size64.get32();
    jbyteArray arrayObj = env->NewByteArray(size);
    jbyteArray arrayObj = env->NewByteArray(size);
    if (arrayObj) {
    if (arrayObj) {
        // TODO: make this work without jniGetNonMovableArrayElements
        // TODO: make this work without jniGetNonMovableArrayElements
        jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj);
        jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj);
        if (addr) {
        if (addr) {
            SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
            SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr,
                    bitmap->rowBytes(), arrayObj, ctable);
            bitmap->setPixelRef(pr)->unref();
            bitmap->setPixelRef(pr)->unref();
            // since we're already allocated, we lockPixels right away
            // since we're already allocated, we lockPixels right away
            // HeapAllocator behaves this way too
            // HeapAllocator behaves this way too
Loading