Loading api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -13048,6 +13048,8 @@ package android.graphics { method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(android.graphics.Picture); method public static android.graphics.Bitmap createBitmap(android.graphics.Picture, int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, boolean); method public int describeContents(); method public void eraseColor(int); Loading Loading @@ -14105,6 +14107,7 @@ package android.graphics { method public void endRecording(); method public int getHeight(); method public int getWidth(); method public boolean requiresHardwareAcceleration(); method public deprecated void writeToStream(java.io.OutputStream); } graphics/java/android/graphics/BaseCanvas.java +12 −3 Original line number Diff line number Diff line Loading @@ -541,10 +541,19 @@ public abstract class BaseCanvas { return mAllowHwBitmapsInSwMode; } /** * @hide */ protected void onHwBitmapInSwMode() { if (!mAllowHwBitmapsInSwMode) { throw new IllegalArgumentException( "Software rendering doesn't support hardware bitmaps"); } } private void throwIfHwBitmapInSwMode(Bitmap bitmap) { if (!mAllowHwBitmapsInSwMode && !isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE) { throw new IllegalStateException("Software rendering doesn't support hardware bitmaps"); if (!isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE) { onHwBitmapInSwMode(); } } Loading graphics/java/android/graphics/Bitmap.java +86 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,10 @@ import android.os.StrictMode; import android.os.Trace; import android.util.DisplayMetrics; import android.util.Log; import android.view.DisplayListCanvas; import android.view.RenderNode; import android.view.ThreadedRenderer; import libcore.util.NativeAllocationRegistry; import java.io.OutputStream; Loading Loading @@ -1170,6 +1174,82 @@ public final class Bitmap implements Parcelable { return createBitmap(display, colors, 0, width, width, height, config); } /** * Creates a Bitmap from the given {@link Picture} source of recorded drawing commands. * * Equivalent to calling {@link #createBitmap(Picture, int, int, Config)} with * width and height the same as the Picture's width and height and a Config.HARDWARE * config. * * @param source The recorded {@link Picture} of drawing commands that will be * drawn into the returned Bitmap. * @return An immutable bitmap with a HARDWARE config whose contents are created * from the recorded drawing commands in the Picture source. */ public static @NonNull Bitmap createBitmap(@NonNull Picture source) { return createBitmap(source, source.getWidth(), source.getHeight(), Config.HARDWARE); } /** * Creates a Bitmap from the given {@link Picture} source of recorded drawing commands. * * The bitmap will be immutable with the given width and height. If the width and height * are not the same as the Picture's width & height, the Picture will be scaled to * fit the given width and height. * * @param source The recorded {@link Picture} of drawing commands that will be * drawn into the returned Bitmap. * @param width The width of the bitmap to create. The picture's width will be * scaled to match if necessary. * @param height The height of the bitmap to create. The picture's height will be * scaled to match if necessary. * @param config The {@link Config} of the created bitmap. If this is null then * the bitmap will be {@link Config#HARDWARE}. * * @return An immutable bitmap with a HARDWARE config whose contents are created * from the recorded drawing commands in the Picture source. */ public static @NonNull Bitmap createBitmap(@NonNull Picture source, int width, int height, @NonNull Config config) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width & height must be > 0"); } if (config == null) { throw new IllegalArgumentException("Config must not be null"); } if (source.requiresHardwareAcceleration() && config != Config.HARDWARE) { StrictMode.noteSlowCall("GPU readback"); } if (config == Config.HARDWARE || source.requiresHardwareAcceleration()) { final RenderNode node = RenderNode.create("BitmapTemporary", null); node.setLeftTopRightBottom(0, 0, width, height); node.setClipToBounds(false); final DisplayListCanvas canvas = node.start(width, height); if (source.getWidth() != width || source.getHeight() != height) { canvas.scale(width / (float) source.getWidth(), height / (float) source.getHeight()); } canvas.drawPicture(source); node.end(canvas); Bitmap bitmap = ThreadedRenderer.createHardwareBitmap(node, width, height); if (config != Config.HARDWARE) { bitmap = bitmap.copy(config, false); } return bitmap; } else { Bitmap bitmap = Bitmap.createBitmap(width, height, config); Canvas canvas = new Canvas(bitmap); if (source.getWidth() != width || source.getHeight() != height) { canvas.scale(width / (float) source.getWidth(), height / (float) source.getHeight()); } canvas.drawPicture(source); canvas.setBitmap(null); bitmap.makeImmutable(); return bitmap; } } /** * Returns an optional array of private data, used by the UI system for * some bitmaps. Not intended to be called by applications. Loading Loading @@ -1259,6 +1339,12 @@ public final class Bitmap implements Parcelable { return mIsMutable; } /** @hide */ public final void makeImmutable() { // todo mIsMutable = false; // todo nMakeImmutable(); } /** * <p>Indicates whether pixels stored in this bitmaps are stored pre-multiplied. * When a pixel is pre-multiplied, the RGB components have been multiplied by Loading graphics/java/android/graphics/Picture.java +32 −6 Original line number Diff line number Diff line Loading @@ -31,8 +31,9 @@ import java.io.OutputStream; * be replayed on a hardware accelerated canvas.</p> */ public class Picture { private Canvas mRecordingCanvas; private PictureCanvas mRecordingCanvas; private long mNativePicture; private boolean mRequiresHwAcceleration; private static final int WORKING_STREAM_STORAGE = 16 * 1024; Loading Loading @@ -78,8 +79,12 @@ public class Picture { * into it. */ public Canvas beginRecording(int width, int height) { if (mRecordingCanvas != null) { throw new IllegalStateException("Picture already recording, must call #endRecording()"); } long ni = nativeBeginRecording(mNativePicture, width, height); mRecordingCanvas = new RecordingCanvas(this, ni); mRecordingCanvas = new PictureCanvas(this, ni); mRequiresHwAcceleration = false; return mRecordingCanvas; } Loading @@ -91,6 +96,7 @@ public class Picture { */ public void endRecording() { if (mRecordingCanvas != null) { mRequiresHwAcceleration = mRecordingCanvas.mHoldsHwBitmap; mRecordingCanvas = null; nativeEndRecording(mNativePicture); } Loading @@ -112,6 +118,18 @@ public class Picture { return nativeGetHeight(mNativePicture); } /** * Indicates whether or not this Picture contains recorded commands that only work when * drawn to a hardware-accelerated canvas. If this returns true then this Picture can only * be drawn to another Picture or to a Canvas where canvas.isHardwareAccelerated() is true. * * @return true if the Picture can only be drawn to a hardware-accelerated canvas, * false otherwise. */ public boolean requiresHardwareAcceleration() { return mRequiresHwAcceleration; } /** * Draw this picture on the canvas. * <p> Loading @@ -129,6 +147,9 @@ public class Picture { if (mRecordingCanvas != null) { endRecording(); } if (mRequiresHwAcceleration && !canvas.isHardwareAccelerated()) { canvas.onHwBitmapInSwMode(); } nativeDraw(canvas.getNativeCanvasWrapper(), mNativePicture); } Loading Loading @@ -164,8 +185,7 @@ public class Picture { if (stream == null) { throw new NullPointerException(); } if (!nativeWriteToStream(mNativePicture, stream, new byte[WORKING_STREAM_STORAGE])) { if (!nativeWriteToStream(mNativePicture, stream, new byte[WORKING_STREAM_STORAGE])) { throw new RuntimeException(); } } Loading @@ -182,10 +202,11 @@ public class Picture { OutputStream stream, byte[] storage); private static native void nativeDestructor(long nativePicture); private static class RecordingCanvas extends Canvas { private static class PictureCanvas extends Canvas { private final Picture mPicture; boolean mHoldsHwBitmap; public RecordingCanvas(Picture pict, long nativeCanvas) { public PictureCanvas(Picture pict, long nativeCanvas) { super(nativeCanvas); mPicture = pict; } Loading @@ -202,5 +223,10 @@ public class Picture { } super.drawPicture(picture); } @Override protected void onHwBitmapInSwMode() { mHoldsHwBitmap = true; } } } Loading
api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -13048,6 +13048,8 @@ package android.graphics { method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(android.graphics.Picture); method public static android.graphics.Bitmap createBitmap(android.graphics.Picture, int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, boolean); method public int describeContents(); method public void eraseColor(int); Loading Loading @@ -14105,6 +14107,7 @@ package android.graphics { method public void endRecording(); method public int getHeight(); method public int getWidth(); method public boolean requiresHardwareAcceleration(); method public deprecated void writeToStream(java.io.OutputStream); }
graphics/java/android/graphics/BaseCanvas.java +12 −3 Original line number Diff line number Diff line Loading @@ -541,10 +541,19 @@ public abstract class BaseCanvas { return mAllowHwBitmapsInSwMode; } /** * @hide */ protected void onHwBitmapInSwMode() { if (!mAllowHwBitmapsInSwMode) { throw new IllegalArgumentException( "Software rendering doesn't support hardware bitmaps"); } } private void throwIfHwBitmapInSwMode(Bitmap bitmap) { if (!mAllowHwBitmapsInSwMode && !isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE) { throw new IllegalStateException("Software rendering doesn't support hardware bitmaps"); if (!isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE) { onHwBitmapInSwMode(); } } Loading
graphics/java/android/graphics/Bitmap.java +86 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,10 @@ import android.os.StrictMode; import android.os.Trace; import android.util.DisplayMetrics; import android.util.Log; import android.view.DisplayListCanvas; import android.view.RenderNode; import android.view.ThreadedRenderer; import libcore.util.NativeAllocationRegistry; import java.io.OutputStream; Loading Loading @@ -1170,6 +1174,82 @@ public final class Bitmap implements Parcelable { return createBitmap(display, colors, 0, width, width, height, config); } /** * Creates a Bitmap from the given {@link Picture} source of recorded drawing commands. * * Equivalent to calling {@link #createBitmap(Picture, int, int, Config)} with * width and height the same as the Picture's width and height and a Config.HARDWARE * config. * * @param source The recorded {@link Picture} of drawing commands that will be * drawn into the returned Bitmap. * @return An immutable bitmap with a HARDWARE config whose contents are created * from the recorded drawing commands in the Picture source. */ public static @NonNull Bitmap createBitmap(@NonNull Picture source) { return createBitmap(source, source.getWidth(), source.getHeight(), Config.HARDWARE); } /** * Creates a Bitmap from the given {@link Picture} source of recorded drawing commands. * * The bitmap will be immutable with the given width and height. If the width and height * are not the same as the Picture's width & height, the Picture will be scaled to * fit the given width and height. * * @param source The recorded {@link Picture} of drawing commands that will be * drawn into the returned Bitmap. * @param width The width of the bitmap to create. The picture's width will be * scaled to match if necessary. * @param height The height of the bitmap to create. The picture's height will be * scaled to match if necessary. * @param config The {@link Config} of the created bitmap. If this is null then * the bitmap will be {@link Config#HARDWARE}. * * @return An immutable bitmap with a HARDWARE config whose contents are created * from the recorded drawing commands in the Picture source. */ public static @NonNull Bitmap createBitmap(@NonNull Picture source, int width, int height, @NonNull Config config) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width & height must be > 0"); } if (config == null) { throw new IllegalArgumentException("Config must not be null"); } if (source.requiresHardwareAcceleration() && config != Config.HARDWARE) { StrictMode.noteSlowCall("GPU readback"); } if (config == Config.HARDWARE || source.requiresHardwareAcceleration()) { final RenderNode node = RenderNode.create("BitmapTemporary", null); node.setLeftTopRightBottom(0, 0, width, height); node.setClipToBounds(false); final DisplayListCanvas canvas = node.start(width, height); if (source.getWidth() != width || source.getHeight() != height) { canvas.scale(width / (float) source.getWidth(), height / (float) source.getHeight()); } canvas.drawPicture(source); node.end(canvas); Bitmap bitmap = ThreadedRenderer.createHardwareBitmap(node, width, height); if (config != Config.HARDWARE) { bitmap = bitmap.copy(config, false); } return bitmap; } else { Bitmap bitmap = Bitmap.createBitmap(width, height, config); Canvas canvas = new Canvas(bitmap); if (source.getWidth() != width || source.getHeight() != height) { canvas.scale(width / (float) source.getWidth(), height / (float) source.getHeight()); } canvas.drawPicture(source); canvas.setBitmap(null); bitmap.makeImmutable(); return bitmap; } } /** * Returns an optional array of private data, used by the UI system for * some bitmaps. Not intended to be called by applications. Loading Loading @@ -1259,6 +1339,12 @@ public final class Bitmap implements Parcelable { return mIsMutable; } /** @hide */ public final void makeImmutable() { // todo mIsMutable = false; // todo nMakeImmutable(); } /** * <p>Indicates whether pixels stored in this bitmaps are stored pre-multiplied. * When a pixel is pre-multiplied, the RGB components have been multiplied by Loading
graphics/java/android/graphics/Picture.java +32 −6 Original line number Diff line number Diff line Loading @@ -31,8 +31,9 @@ import java.io.OutputStream; * be replayed on a hardware accelerated canvas.</p> */ public class Picture { private Canvas mRecordingCanvas; private PictureCanvas mRecordingCanvas; private long mNativePicture; private boolean mRequiresHwAcceleration; private static final int WORKING_STREAM_STORAGE = 16 * 1024; Loading Loading @@ -78,8 +79,12 @@ public class Picture { * into it. */ public Canvas beginRecording(int width, int height) { if (mRecordingCanvas != null) { throw new IllegalStateException("Picture already recording, must call #endRecording()"); } long ni = nativeBeginRecording(mNativePicture, width, height); mRecordingCanvas = new RecordingCanvas(this, ni); mRecordingCanvas = new PictureCanvas(this, ni); mRequiresHwAcceleration = false; return mRecordingCanvas; } Loading @@ -91,6 +96,7 @@ public class Picture { */ public void endRecording() { if (mRecordingCanvas != null) { mRequiresHwAcceleration = mRecordingCanvas.mHoldsHwBitmap; mRecordingCanvas = null; nativeEndRecording(mNativePicture); } Loading @@ -112,6 +118,18 @@ public class Picture { return nativeGetHeight(mNativePicture); } /** * Indicates whether or not this Picture contains recorded commands that only work when * drawn to a hardware-accelerated canvas. If this returns true then this Picture can only * be drawn to another Picture or to a Canvas where canvas.isHardwareAccelerated() is true. * * @return true if the Picture can only be drawn to a hardware-accelerated canvas, * false otherwise. */ public boolean requiresHardwareAcceleration() { return mRequiresHwAcceleration; } /** * Draw this picture on the canvas. * <p> Loading @@ -129,6 +147,9 @@ public class Picture { if (mRecordingCanvas != null) { endRecording(); } if (mRequiresHwAcceleration && !canvas.isHardwareAccelerated()) { canvas.onHwBitmapInSwMode(); } nativeDraw(canvas.getNativeCanvasWrapper(), mNativePicture); } Loading Loading @@ -164,8 +185,7 @@ public class Picture { if (stream == null) { throw new NullPointerException(); } if (!nativeWriteToStream(mNativePicture, stream, new byte[WORKING_STREAM_STORAGE])) { if (!nativeWriteToStream(mNativePicture, stream, new byte[WORKING_STREAM_STORAGE])) { throw new RuntimeException(); } } Loading @@ -182,10 +202,11 @@ public class Picture { OutputStream stream, byte[] storage); private static native void nativeDestructor(long nativePicture); private static class RecordingCanvas extends Canvas { private static class PictureCanvas extends Canvas { private final Picture mPicture; boolean mHoldsHwBitmap; public RecordingCanvas(Picture pict, long nativeCanvas) { public PictureCanvas(Picture pict, long nativeCanvas) { super(nativeCanvas); mPicture = pict; } Loading @@ -202,5 +223,10 @@ public class Picture { } super.drawPicture(picture); } @Override protected void onHwBitmapInSwMode() { mHoldsHwBitmap = true; } } }