Loading core/jni/android/graphics/Bitmap.cpp +10 −4 Original line number Diff line number Diff line 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 @@ -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 +5 −2 Original line number Diff line number Diff line Loading @@ -401,8 +401,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 core/jni/android/graphics/Graphics.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,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 @@ -360,6 +372,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 @@ -377,6 +393,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 core/jni/android/graphics/GraphicsJNI.h +4 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ public: /** Create a java Bitmap object given the native bitmap (required) and optional storage array (may be null). bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. */ static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1); Loading @@ -64,6 +65,9 @@ public: static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags, jbyteArray ninepatch, int density = -1); /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in sync with isPremultiplied */ static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, bool isPremultiplied); Loading core/jni/android_view_Surface.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <SkCanvas.h> #include <SkBitmap.h> #include <SkImage.h> #include <SkRegion.h> #include <utils/misc.h> Loading Loading @@ -178,7 +179,8 @@ static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jint na static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then we can map to SkBitmap::kARGB_8888_Config, and optionally call bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator) bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap (as an accelerator) */ switch (format) { case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config; Loading Loading @@ -234,7 +236,7 @@ static jint nativeLockCanvas(JNIEnv* env, jclass clazz, ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format); bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr); if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) { bitmap.setIsOpaque(true); bitmap.setAlphaType(kOpaque_SkAlphaType); } if (outBuffer.width > 0 && outBuffer.height > 0) { bitmap.setPixels(outBuffer.bits); Loading Loading
core/jni/android/graphics/Bitmap.cpp +10 −4 Original line number Diff line number Diff line 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 @@ -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 +5 −2 Original line number Diff line number Diff line Loading @@ -401,8 +401,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
core/jni/android/graphics/Graphics.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,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 @@ -360,6 +372,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 @@ -377,6 +393,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
core/jni/android/graphics/GraphicsJNI.h +4 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ public: /** Create a java Bitmap object given the native bitmap (required) and optional storage array (may be null). bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. */ static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1); Loading @@ -64,6 +65,9 @@ public: static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags, jbyteArray ninepatch, int density = -1); /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in sync with isPremultiplied */ static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, bool isPremultiplied); Loading
core/jni/android_view_Surface.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <SkCanvas.h> #include <SkBitmap.h> #include <SkImage.h> #include <SkRegion.h> #include <utils/misc.h> Loading Loading @@ -178,7 +179,8 @@ static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jint na static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then we can map to SkBitmap::kARGB_8888_Config, and optionally call bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator) bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap (as an accelerator) */ switch (format) { case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config; Loading Loading @@ -234,7 +236,7 @@ static jint nativeLockCanvas(JNIEnv* env, jclass clazz, ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format); bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr); if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) { bitmap.setIsOpaque(true); bitmap.setAlphaType(kOpaque_SkAlphaType); } if (outBuffer.width > 0 && outBuffer.height > 0) { bitmap.setPixels(outBuffer.bits); Loading