In Bitmap.reconfigure, update the pixelref's info.
This fixes CTS tests which are crashing on an SkASSERT due to a mismatch of SkImageInfo between the SkPixelRef and SkBitmap. Also directly call ref() and unref() instead of SkSafeRef/SkSafeUnref, since we would already crash if the SkPixelRef in question was NULL. Also if the user attempts to reconfigure to 4444, use 8888 instead. Change-Id: I473ef225c6cd1c92d67ae103c53c6cff0dad92de
This commit is contained in:
@@ -361,24 +361,50 @@ static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
|
||||
}
|
||||
|
||||
static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle,
|
||||
jint width, jint height, jint configHandle, jint allocSize) {
|
||||
jint width, jint height, jint configHandle, jint allocSize,
|
||||
jboolean requestPremul) {
|
||||
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
|
||||
SkBitmap::Config config = static_cast<SkBitmap::Config>(configHandle);
|
||||
if (width * height * SkBitmap::ComputeBytesPerPixel(config) > allocSize) {
|
||||
SkColorType colorType = SkBitmapConfigToColorType(config);
|
||||
|
||||
// ARGB_4444 is a deprecated format, convert automatically to 8888
|
||||
if (colorType == kARGB_4444_SkColorType) {
|
||||
colorType = kN32_SkColorType;
|
||||
}
|
||||
|
||||
if (width * height * SkColorTypeBytesPerPixel(colorType) > allocSize) {
|
||||
// done in native as there's no way to get BytesPerPixel in Java
|
||||
doThrowIAE(env, "Bitmap not large enough to support new configuration");
|
||||
return;
|
||||
}
|
||||
SkPixelRef* ref = bitmap->pixelRef();
|
||||
SkSafeRef(ref);
|
||||
bitmap->setConfig(config, width, height);
|
||||
ref->ref();
|
||||
SkAlphaType alphaType;
|
||||
if (bitmap->colorType() != kRGB_565_SkColorType
|
||||
&& bitmap->alphaType() == kOpaque_SkAlphaType) {
|
||||
// If the original bitmap was set to opaque, keep that setting, unless it
|
||||
// was 565, which is required to be opaque.
|
||||
alphaType = kOpaque_SkAlphaType;
|
||||
} else {
|
||||
// Otherwise respect the premultiplied request.
|
||||
alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType;
|
||||
}
|
||||
bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType));
|
||||
// FIXME: Skia thinks of an SkPixelRef as having a constant SkImageInfo (except for
|
||||
// its alphatype), so it would make more sense from Skia's perspective to create a
|
||||
// new SkPixelRef. That said, libhwui uses the pointer to the SkPixelRef as a key
|
||||
// for its cache, so it won't realize this is the same Java Bitmap.
|
||||
SkImageInfo& info = const_cast<SkImageInfo&>(ref->info());
|
||||
// Use the updated from the SkBitmap, which may have corrected an invalid alphatype.
|
||||
// (e.g. 565 non-opaque)
|
||||
info = bitmap->info();
|
||||
bitmap->setPixelRef(ref);
|
||||
|
||||
// notifyPixelsChanged will increment the generation ID even though the actual pixel data
|
||||
// hasn't been touched. This signals the renderer that the bitmap (including width, height,
|
||||
// and config) has changed.
|
||||
// colortype and alphatype) has changed.
|
||||
ref->notifyPixelsChanged();
|
||||
SkSafeUnref(ref);
|
||||
ref->unref();
|
||||
}
|
||||
|
||||
// These must match the int values in Bitmap.java
|
||||
@@ -799,7 +825,7 @@ static JNINativeMethod gBitmapMethods[] = {
|
||||
(void*)Bitmap_copy },
|
||||
{ "nativeDestructor", "(J)V", (void*)Bitmap_destructor },
|
||||
{ "nativeRecycle", "(J)Z", (void*)Bitmap_recycle },
|
||||
{ "nativeReconfigure", "(JIIII)V", (void*)Bitmap_reconfigure },
|
||||
{ "nativeReconfigure", "(JIIIIZ)V", (void*)Bitmap_reconfigure },
|
||||
{ "nativeCompress", "(JIILjava/io/OutputStream;[B)Z",
|
||||
(void*)Bitmap_compress },
|
||||
{ "nativeErase", "(JI)V", (void*)Bitmap_erase },
|
||||
|
||||
@@ -194,6 +194,11 @@ public final class Bitmap implements Parcelable {
|
||||
* while {@link #getAllocationByteCount()} will reflect that of the initial
|
||||
* configuration.</p>
|
||||
*
|
||||
* <p>Note: This may change this result of hasAlpha(). When converting to 565,
|
||||
* the new bitmap will always be considered opaque. When converting from 565,
|
||||
* the new bitmap will be considered non-opaque, and will respect the value
|
||||
* set by setPremultiplied().</p>
|
||||
*
|
||||
* <p>WARNING: This method should NOT be called on a bitmap currently used
|
||||
* by the view system. It does not make guarantees about how the underlying
|
||||
* pixel buffer is remapped to the new config, just that the allocation is
|
||||
@@ -217,7 +222,8 @@ public final class Bitmap implements Parcelable {
|
||||
throw new IllegalStateException("native-backed bitmaps may not be reconfigured");
|
||||
}
|
||||
|
||||
nativeReconfigure(mNativeBitmap, width, height, config.nativeInt, mBuffer.length);
|
||||
nativeReconfigure(mNativeBitmap, width, height, config.nativeInt, mBuffer.length,
|
||||
mIsPremultiplied);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
}
|
||||
@@ -1586,7 +1592,8 @@ public final class Bitmap implements Parcelable {
|
||||
private static native void nativeDestructor(long nativeBitmap);
|
||||
private static native boolean nativeRecycle(long nativeBitmap);
|
||||
private static native void nativeReconfigure(long nativeBitmap, int width, int height,
|
||||
int config, int allocSize);
|
||||
int config, int allocSize,
|
||||
boolean isPremultiplied);
|
||||
|
||||
private static native boolean nativeCompress(long nativeBitmap, int format,
|
||||
int quality, OutputStream stream,
|
||||
|
||||
Reference in New Issue
Block a user