diff options
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/jni/android/graphics/BitmapFactory.cpp | 5 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 21 | ||||
| -rw-r--r-- | graphics/java/android/graphics/BitmapFactory.java | 36 | ||||
| -rw-r--r-- | graphics/java/android/graphics/BitmapRegionDecoder.java | 4 |
7 files changed, 63 insertions, 6 deletions
diff --git a/api/current.txt b/api/current.txt index 0209b5e1aeeb..3af2c8f21c14 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11779,6 +11779,7 @@ package android.graphics { enum_constant public static final android.graphics.Bitmap.Config ALPHA_8; enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444; enum_constant public static final android.graphics.Bitmap.Config ARGB_8888; + enum_constant public static final android.graphics.Bitmap.Config HARDWARE; enum_constant public static final android.graphics.Bitmap.Config RGB_565; } diff --git a/api/system-current.txt b/api/system-current.txt index 1d14343f2530..8034c3bb7d83 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -12265,6 +12265,7 @@ package android.graphics { enum_constant public static final android.graphics.Bitmap.Config ALPHA_8; enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444; enum_constant public static final android.graphics.Bitmap.Config ARGB_8888; + enum_constant public static final android.graphics.Bitmap.Config HARDWARE; enum_constant public static final android.graphics.Bitmap.Config RGB_565; } diff --git a/api/test-current.txt b/api/test-current.txt index 2ef7fa54d332..f10fdb089a03 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -11810,6 +11810,7 @@ package android.graphics { enum_constant public static final android.graphics.Bitmap.Config ALPHA_8; enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444; enum_constant public static final android.graphics.Bitmap.Config ARGB_8888; + enum_constant public static final android.graphics.Bitmap.Config HARDWARE; enum_constant public static final android.graphics.Bitmap.Config RGB_565; } diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index e86acc4b200c..762a3f35ad9e 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -276,6 +276,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } } + if (isMutable && isHardware) { + doThrowIAE(env, "Bitmaps with Config.HARWARE are always immutable"); + return nullObjectReturn("Cannot create mutable hardware bitmap"); + } + // Create the codec. NinePatchPeeker peeker; std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(), diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 756087c75db0..cd75fe95121a 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -467,7 +467,11 @@ public final class Bitmap implements Parcelable { /** - * @hide + * Special configuration, when bitmap is stored only in graphic memory. + * Bitmaps in this configuration are always immutable. + * + * It is optimal for cases, when the only operation with the bitmap is to draw it on a + * screen. */ HARDWARE (6); @@ -810,7 +814,8 @@ public final class Bitmap implements Parcelable { * @param width The width of the bitmap * @param height The height of the bitmap * @param config The bitmap config to create. - * @throws IllegalArgumentException if the width or height are <= 0 + * @throws IllegalArgumentException if the width or height are <= 0, or if + * Config is Config.HARDWARE, because hardware bitmaps are always immutable */ public static Bitmap createBitmap(int width, int height, Config config) { return createBitmap(width, height, config, true); @@ -825,7 +830,8 @@ public final class Bitmap implements Parcelable { * @param width The width of the bitmap * @param height The height of the bitmap * @param config The bitmap config to create. - * @throws IllegalArgumentException if the width or height are <= 0 + * @throws IllegalArgumentException if the width or height are <= 0, or if + * Config is Config.HARDWARE, because hardware bitmaps are always immutable */ public static Bitmap createBitmap(DisplayMetrics display, int width, int height, Config config) { @@ -843,7 +849,8 @@ public final class Bitmap implements Parcelable { * bitmap as opaque. Doing so will clear the bitmap in black * instead of transparent. * - * @throws IllegalArgumentException if the width or height are <= 0 + * @throws IllegalArgumentException if the width or height are <= 0, or if + * Config is Config.HARDWARE, because hardware bitmaps are always immutable */ private static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) { return createBitmap(null, width, height, config, hasAlpha); @@ -862,13 +869,17 @@ public final class Bitmap implements Parcelable { * bitmap as opaque. Doing so will clear the bitmap in black * instead of transparent. * - * @throws IllegalArgumentException if the width or height are <= 0 + * @throws IllegalArgumentException if the width or height are <= 0, or if + * Config is Config.HARDWARE, because hardware bitmaps are always immutable */ private static Bitmap createBitmap(DisplayMetrics display, int width, int height, Config config, boolean hasAlpha) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } + if (config == Config.HARDWARE) { + throw new IllegalArgumentException("can't create mutable bitmap with Config.HARDWARE"); + } Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true); if (display != null) { bm.mDensity = display.densityDpi; diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 447a4c4e8345..a5517f091d3c 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -16,6 +16,8 @@ package android.graphics; +import static android.graphics.BitmapFactory.Options.validate; + import android.content.res.AssetManager; import android.content.res.Resources; import android.os.Trace; @@ -103,6 +105,9 @@ public class BitmapFactory { * If set, decode methods will always return a mutable Bitmap instead of * an immutable one. This can be used for instance to programmatically apply * effects to a Bitmap loaded through BitmapFactory. + * <p>Can not be set simultaneously with inPreferredConfig = + * {@link android.graphics.Bitmap.Config#HARDWARE}, + * because hardware bitmaps are always immutable. */ @SuppressWarnings({"UnusedDeclaration"}) // used in native code public boolean inMutable; @@ -381,6 +386,12 @@ public class BitmapFactory { public void requestCancelDecode() { mCancel = true; } + + static void validate(Options opts) { + if (opts != null && opts.inMutable && opts.inPreferredConfig == Bitmap.Config.HARDWARE) { + throw new IllegalArgumentException("Bitmaps with Config.HARWARE are always immutable"); + } + } } /** @@ -393,8 +404,12 @@ public class BitmapFactory { * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. */ public static Bitmap decodeFile(String pathName, Options opts) { + validate(opts); Bitmap bm = null; InputStream stream = null; try { @@ -431,10 +446,13 @@ public class BitmapFactory { /** * Decode a new Bitmap from an InputStream. This InputStream was obtained from * resources, which we pass to be able to scale the bitmap accordingly. + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. */ public static Bitmap decodeResourceStream(Resources res, TypedValue value, InputStream is, Rect pad, Options opts) { - + validate(opts); if (opts == null) { opts = new Options(); } @@ -466,8 +484,12 @@ public class BitmapFactory { * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. */ public static Bitmap decodeResource(Resources res, int id, Options opts) { + validate(opts); Bitmap bm = null; InputStream is = null; @@ -520,11 +542,15 @@ public class BitmapFactory { * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. */ public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) { if ((offset | length) < 0 || data.length < offset + length) { throw new ArrayIndexOutOfBoundsException(); } + validate(opts); Bitmap bm; @@ -598,6 +624,9 @@ public class BitmapFactory { * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. * * <p class="note">Prior to {@link android.os.Build.VERSION_CODES#KITKAT}, * if {@link InputStream#markSupported is.markSupported()} returns true, @@ -610,6 +639,7 @@ public class BitmapFactory { if (is == null) { return null; } + validate(opts); Bitmap bm = null; @@ -673,8 +703,12 @@ public class BitmapFactory { * @param opts null-ok; Options that control downsampling and whether the * image should be completely decoded, or just its size returned. * @return the decoded bitmap, or null + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. */ public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) { + validate(opts); Bitmap bm; Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeFileDescriptor"); diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java index e689b083ad97..04abca1f4bd4 100644 --- a/graphics/java/android/graphics/BitmapRegionDecoder.java +++ b/graphics/java/android/graphics/BitmapRegionDecoder.java @@ -178,8 +178,12 @@ public final class BitmapRegionDecoder { * inPurgeable is not supported. * @return The decoded bitmap, or null if the image data could not be * decoded. + * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig} + * is {@link android.graphics.Bitmap.Config#HARDWARE} + * and {@link BitmapFactory.Options#inMutable} is set. */ public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { + BitmapFactory.Options.validate(options); synchronized (mNativeLock) { checkRecycled("decodeRegion called on recycled region decoder"); if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth() |