Loading core/jni/android/graphics/Bitmap.cpp +15 −9 Original line number Diff line number Diff line Loading @@ -227,7 +227,7 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, do { *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); } while (--width != 0); ctable->unlockColors(false); ctable->unlockColors(); } static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, Loading @@ -240,7 +240,7 @@ static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); } while (--width != 0); ctable->unlockColors(false); ctable->unlockColors(); } static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, Loading @@ -253,7 +253,7 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); } while (--width != 0); ctable->unlockColors(false); ctable->unlockColors(); } // can return NULL Loading Loading @@ -442,9 +442,15 @@ static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap) { return !bitmap->isOpaque(); } static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap, jboolean hasAlpha) { bitmap->setIsOpaque(!hasAlpha); static void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, SkBitmap* bitmap, jboolean hasAlpha, jboolean isPremul) { 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) { Loading Loading @@ -543,14 +549,14 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, p->writeInt32(bitmap->rowBytes()); p->writeInt32(density); if (bitmap->getConfig() == SkBitmap::kIndex8_Config) { if (bitmap->config() == SkBitmap::kIndex8_Config) { SkColorTable* ctable = bitmap->getColorTable(); if (ctable != NULL) { int count = ctable->count(); p->writeInt32(count); memcpy(p->writeInplace(count * sizeof(SkPMColor)), ctable->lockColors(), count * sizeof(SkPMColor)); ctable->unlockColors(false); ctable->unlockColors(); } else { p->writeInt32(0); // indicate no ctable } Loading Loading @@ -770,7 +776,7 @@ static JNINativeMethod gBitmapMethods[] = { { "nativeRowBytes", "(I)I", (void*)Bitmap_rowBytes }, { "nativeConfig", "(I)I", (void*)Bitmap_config }, { "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha }, { "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha }, { "nativeSetAlphaAndPremultiplied", "(IZZ)V", (void*)Bitmap_setAlphaAndPremultiplied}, { "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap }, { "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap }, { "nativeCreateFromParcel", Loading core/jni/android/graphics/BitmapFactory.cpp +26 −8 Original line number Diff line number Diff line Loading @@ -124,12 +124,18 @@ static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) { static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream, 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; // only use ashmem for large images, since mmaps come at a price if (bitmap->getSize() >= 32 * 1024) { pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize); pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize); } else { pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize); pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize); } pr->setDitherImage(ditherImage); bitmap->setPixelRef(pr)->unref(); Loading Loading @@ -157,7 +163,7 @@ public: virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) { // accounts for scale in final allocation, using eventual size and config const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel( configForScaledOutput(bitmap->getConfig())); configForScaledOutput(bitmap->config())); const int requestedSize = bytesPerPixel * int(bitmap->width() * mScale + 0.5f) * int(bitmap->height() * mScale + 0.5f); Loading Loading @@ -191,8 +197,15 @@ public: 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 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(); // since we're already allocated, we lockPixels right away Loading Loading @@ -401,8 +414,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding // TODO: avoid copying when scaled size equals decodingBitmap size SkBitmap::Config config = configForScaledOutput(decodingBitmap.config()); outputBitmap->setConfig(config, scaledWidth, scaledHeight); outputBitmap->setIsOpaque(decodingBitmap.isOpaque()); // FIXME: If the alphaType is kUnpremul and the image has alpha, the // 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)) { return nullObjectReturn("allocation failed for scaled bitmap"); } Loading @@ -414,7 +430,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } SkPaint paint; paint.setFilterBitmap(true); paint.setFilterLevel(SkPaint::kLow_FilterLevel); SkCanvas canvas(*outputBitmap); canvas.scale(sx, sy); Loading Loading @@ -541,7 +557,9 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset, } else { // since we know we'll be done with the asset when we return, we can // just use a simple wrapper stream = new AssetStreamAdaptor(asset); stream = new AssetStreamAdaptor(asset, AssetStreamAdaptor::kNo_OwnAsset, AssetStreamAdaptor::kNo_HasMemoryBase); } SkAutoUnref aur(stream); return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable); Loading core/jni/android/graphics/BitmapRegionDecoder.cpp +4 −5 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ #include "CreateJavaOutputStreamAdaptor.h" #include "Utils.h" #include "JNIHelp.h" #include "SkTScopedPtr.h" #include <android_runtime/AndroidRuntime.h> #include "android_util_Binder.h" Loading Loading @@ -76,7 +75,7 @@ private: int fHeight; }; static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) { static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) { SkImageDecoder* decoder = SkImageDecoder::Factory(stream); int width, height; if (NULL == decoder) { Loading Loading @@ -108,7 +107,7 @@ static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray b For now we just always copy the array's data if isShareable. */ 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); SkSafeUnref(stream); // the decoder now holds a reference Loading Loading @@ -215,7 +214,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b region.fRight = start_x + width; region.fBottom = start_y + height; SkBitmap* bitmap = NULL; SkTScopedPtr<SkBitmap> adb; SkAutoTDelete<SkBitmap> adb; if (tileBitmap != NULL) { // Re-use bitmap. Loading Loading @@ -246,7 +245,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b } // detach bitmap from its autodeleter, since we want to own it now adb.release(); adb.detach(); JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator(); jbyteArray buff = allocator->getStorageObjAndReset(); Loading core/jni/android/graphics/Canvas.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -476,7 +476,7 @@ public: if (paint) { filteredPaint = *paint; } filteredPaint.setFilterBitmap(true); filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint); } else { canvas->drawBitmap(*bitmap, left_, top_, paint); Loading @@ -491,7 +491,7 @@ public: if (paint) { filteredPaint = *paint; } filteredPaint.setFilterBitmap(true); filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); Loading @@ -514,7 +514,7 @@ public: if (paint) { filteredPaint = *paint; } filteredPaint.setFilterBitmap(true); filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint); } else { canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint); Loading core/jni/android/graphics/Graphics.cpp +36 −7 Original line number Diff line number Diff line Loading @@ -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, int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density) { Loading @@ -354,6 +366,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buff bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; 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, static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer, bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied, Loading @@ -371,6 +387,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreat void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, 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, bitmap->width(), bitmap->height(), isPremultiplied); } Loading Loading @@ -413,8 +433,9 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)), AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) : SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)), fWrappedPixelRef(NULL) { SkASSERT(storage); SkASSERT(env); Loading @@ -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 fOnJavaHeap = (storageObj != NULL); } AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) : SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false), AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) : SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false), fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ? wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef) { Loading Loading @@ -540,13 +561,21 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, return NULL; } SkImageInfo bitmapInfo; if (!bitmap->asImageInfo(&bitmapInfo)) { jniThrowException(env, "java/lang/IllegalArgumentException", "unknown bitmap configuration"); return NULL; } size_t size = size64.get32(); jbyteArray arrayObj = env->NewByteArray(size); if (arrayObj) { // TODO: make this work without jniGetNonMovableArrayElements jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj); 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(); // since we're already allocated, we lockPixels right away // HeapAllocator behaves this way too Loading Loading
core/jni/android/graphics/Bitmap.cpp +15 −9 Original line number Diff line number Diff line Loading @@ -227,7 +227,7 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, do { *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); } while (--width != 0); ctable->unlockColors(false); ctable->unlockColors(); } static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, Loading @@ -240,7 +240,7 @@ static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); } while (--width != 0); ctable->unlockColors(false); ctable->unlockColors(); } static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, Loading @@ -253,7 +253,7 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); } while (--width != 0); ctable->unlockColors(false); ctable->unlockColors(); } // can return NULL Loading Loading @@ -442,9 +442,15 @@ static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap) { return !bitmap->isOpaque(); } static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap, jboolean hasAlpha) { bitmap->setIsOpaque(!hasAlpha); static void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, SkBitmap* bitmap, jboolean hasAlpha, jboolean isPremul) { 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) { Loading Loading @@ -543,14 +549,14 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, p->writeInt32(bitmap->rowBytes()); p->writeInt32(density); if (bitmap->getConfig() == SkBitmap::kIndex8_Config) { if (bitmap->config() == SkBitmap::kIndex8_Config) { SkColorTable* ctable = bitmap->getColorTable(); if (ctable != NULL) { int count = ctable->count(); p->writeInt32(count); memcpy(p->writeInplace(count * sizeof(SkPMColor)), ctable->lockColors(), count * sizeof(SkPMColor)); ctable->unlockColors(false); ctable->unlockColors(); } else { p->writeInt32(0); // indicate no ctable } Loading Loading @@ -770,7 +776,7 @@ static JNINativeMethod gBitmapMethods[] = { { "nativeRowBytes", "(I)I", (void*)Bitmap_rowBytes }, { "nativeConfig", "(I)I", (void*)Bitmap_config }, { "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha }, { "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha }, { "nativeSetAlphaAndPremultiplied", "(IZZ)V", (void*)Bitmap_setAlphaAndPremultiplied}, { "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap }, { "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap }, { "nativeCreateFromParcel", Loading
core/jni/android/graphics/BitmapFactory.cpp +26 −8 Original line number Diff line number Diff line Loading @@ -124,12 +124,18 @@ static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) { static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream, 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; // only use ashmem for large images, since mmaps come at a price if (bitmap->getSize() >= 32 * 1024) { pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize); pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize); } else { pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize); pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize); } pr->setDitherImage(ditherImage); bitmap->setPixelRef(pr)->unref(); Loading Loading @@ -157,7 +163,7 @@ public: virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) { // accounts for scale in final allocation, using eventual size and config const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel( configForScaledOutput(bitmap->getConfig())); configForScaledOutput(bitmap->config())); const int requestedSize = bytesPerPixel * int(bitmap->width() * mScale + 0.5f) * int(bitmap->height() * mScale + 0.5f); Loading Loading @@ -191,8 +197,15 @@ public: 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 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(); // since we're already allocated, we lockPixels right away Loading Loading @@ -401,8 +414,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding // TODO: avoid copying when scaled size equals decodingBitmap size SkBitmap::Config config = configForScaledOutput(decodingBitmap.config()); outputBitmap->setConfig(config, scaledWidth, scaledHeight); outputBitmap->setIsOpaque(decodingBitmap.isOpaque()); // FIXME: If the alphaType is kUnpremul and the image has alpha, the // 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)) { return nullObjectReturn("allocation failed for scaled bitmap"); } Loading @@ -414,7 +430,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } SkPaint paint; paint.setFilterBitmap(true); paint.setFilterLevel(SkPaint::kLow_FilterLevel); SkCanvas canvas(*outputBitmap); canvas.scale(sx, sy); Loading Loading @@ -541,7 +557,9 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset, } else { // since we know we'll be done with the asset when we return, we can // just use a simple wrapper stream = new AssetStreamAdaptor(asset); stream = new AssetStreamAdaptor(asset, AssetStreamAdaptor::kNo_OwnAsset, AssetStreamAdaptor::kNo_HasMemoryBase); } SkAutoUnref aur(stream); return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable); Loading
core/jni/android/graphics/BitmapRegionDecoder.cpp +4 −5 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ #include "CreateJavaOutputStreamAdaptor.h" #include "Utils.h" #include "JNIHelp.h" #include "SkTScopedPtr.h" #include <android_runtime/AndroidRuntime.h> #include "android_util_Binder.h" Loading Loading @@ -76,7 +75,7 @@ private: int fHeight; }; static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) { static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) { SkImageDecoder* decoder = SkImageDecoder::Factory(stream); int width, height; if (NULL == decoder) { Loading Loading @@ -108,7 +107,7 @@ static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray b For now we just always copy the array's data if isShareable. */ 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); SkSafeUnref(stream); // the decoder now holds a reference Loading Loading @@ -215,7 +214,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b region.fRight = start_x + width; region.fBottom = start_y + height; SkBitmap* bitmap = NULL; SkTScopedPtr<SkBitmap> adb; SkAutoTDelete<SkBitmap> adb; if (tileBitmap != NULL) { // Re-use bitmap. Loading Loading @@ -246,7 +245,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b } // detach bitmap from its autodeleter, since we want to own it now adb.release(); adb.detach(); JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator(); jbyteArray buff = allocator->getStorageObjAndReset(); Loading
core/jni/android/graphics/Canvas.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -476,7 +476,7 @@ public: if (paint) { filteredPaint = *paint; } filteredPaint.setFilterBitmap(true); filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint); } else { canvas->drawBitmap(*bitmap, left_, top_, paint); Loading @@ -491,7 +491,7 @@ public: if (paint) { filteredPaint = *paint; } filteredPaint.setFilterBitmap(true); filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); Loading @@ -514,7 +514,7 @@ public: if (paint) { filteredPaint = *paint; } filteredPaint.setFilterBitmap(true); filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint); } else { canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint); Loading
core/jni/android/graphics/Graphics.cpp +36 −7 Original line number Diff line number Diff line Loading @@ -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, int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density) { Loading @@ -354,6 +366,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buff bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; 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, static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer, bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied, Loading @@ -371,6 +387,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreat void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, 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, bitmap->width(), bitmap->height(), isPremultiplied); } Loading Loading @@ -413,8 +433,9 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)), AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) : SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)), fWrappedPixelRef(NULL) { SkASSERT(storage); SkASSERT(env); Loading @@ -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 fOnJavaHeap = (storageObj != NULL); } AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) : SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false), AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) : SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false), fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ? wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef) { Loading Loading @@ -540,13 +561,21 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, return NULL; } SkImageInfo bitmapInfo; if (!bitmap->asImageInfo(&bitmapInfo)) { jniThrowException(env, "java/lang/IllegalArgumentException", "unknown bitmap configuration"); return NULL; } size_t size = size64.get32(); jbyteArray arrayObj = env->NewByteArray(size); if (arrayObj) { // TODO: make this work without jniGetNonMovableArrayElements jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj); 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(); // since we're already allocated, we lockPixels right away // HeapAllocator behaves this way too Loading