diff options
Diffstat (limited to 'graphics/java/android/renderscript/Allocation.java')
-rw-r--r-- | graphics/java/android/renderscript/Allocation.java | 239 |
1 files changed, 182 insertions, 57 deletions
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index e6a5583afe04..b8564b60bbf2 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -26,6 +26,7 @@ import android.view.Surface; import android.graphics.SurfaceTexture; import android.util.Log; import android.util.TypedValue; +import android.graphics.Canvas; /** * <p> @@ -148,6 +149,19 @@ public class Allocation extends BaseObj { public static final int USAGE_IO_OUTPUT = 0x0040; /** + * USAGE_SHARED The allocation's backing store will be inherited + * from another object (usually a Bitmap); calling appropriate + * copy methods will be significantly faster than if the entire + * allocation were copied every time. + * + * This is set by default for allocations created with + * CreateFromBitmap(RenderScript, Bitmap) in API version 18 and + * higher. + * + */ + public static final int USAGE_SHARED = 0x0080; + + /** * Controls mipmap behavior when using the bitmap creation and * update functions. */ @@ -233,6 +247,10 @@ public class Allocation extends BaseObj { } } + private void setBitmap(Bitmap b) { + mBitmap = b; + } + Allocation(int id, RenderScript rs, Type t, int usage) { super(id, rs); if ((usage & ~(USAGE_SCRIPT | @@ -241,7 +259,8 @@ public class Allocation extends BaseObj { USAGE_GRAPHICS_CONSTANTS | USAGE_GRAPHICS_RENDER_TARGET | USAGE_IO_INPUT | - USAGE_IO_OUTPUT)) != 0) { + USAGE_IO_OUTPUT | + USAGE_SHARED)) != 0) { throw new RSIllegalArgumentException("Unknown usage specified."); } @@ -411,6 +430,9 @@ public class Allocation extends BaseObj { private void validateBitmapFormat(Bitmap b) { Bitmap.Config bc = b.getConfig(); + if (bc == null) { + throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation"); + } switch (bc) { case ALPHA_8: if (mType.getElement().mKind != Element.DataKind.PIXEL_A) { @@ -470,7 +492,11 @@ public class Allocation extends BaseObj { */ public void copyFromUnchecked(int[] d) { mRS.validate(); - copy1DRangeFromUnchecked(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } } /** * Copy an allocation from an array. This variant is not type @@ -481,7 +507,11 @@ public class Allocation extends BaseObj { */ public void copyFromUnchecked(short[] d) { mRS.validate(); - copy1DRangeFromUnchecked(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } } /** * Copy an allocation from an array. This variant is not type @@ -492,7 +522,11 @@ public class Allocation extends BaseObj { */ public void copyFromUnchecked(byte[] d) { mRS.validate(); - copy1DRangeFromUnchecked(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } } /** * Copy an allocation from an array. This variant is not type @@ -503,7 +537,11 @@ public class Allocation extends BaseObj { */ public void copyFromUnchecked(float[] d) { mRS.validate(); - copy1DRangeFromUnchecked(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } } /** @@ -515,7 +553,11 @@ public class Allocation extends BaseObj { */ public void copyFrom(int[] d) { mRS.validate(); - copy1DRangeFrom(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } } /** @@ -527,7 +569,11 @@ public class Allocation extends BaseObj { */ public void copyFrom(short[] d) { mRS.validate(); - copy1DRangeFrom(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } } /** @@ -539,7 +585,11 @@ public class Allocation extends BaseObj { */ public void copyFrom(byte[] d) { mRS.validate(); - copy1DRangeFrom(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } } /** @@ -551,7 +601,11 @@ public class Allocation extends BaseObj { */ public void copyFrom(float[] d) { mRS.validate(); - copy1DRangeFrom(0, mCurrentCount, d); + if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } } /** @@ -562,12 +616,34 @@ public class Allocation extends BaseObj { */ public void copyFrom(Bitmap b) { mRS.validate(); + if (b.getConfig() == null) { + Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(newBitmap); + c.drawBitmap(b, 0, 0, null); + copyFrom(newBitmap); + return; + } validateBitmapSize(b); validateBitmapFormat(b); mRS.nAllocationCopyFromBitmap(getID(mRS), b); } /** + * Copy an allocation from an allocation. The types of both allocations + * must be identical. + * + * @param a the source allocation + */ + public void copyFrom(Allocation a) { + mRS.validate(); + if (!mType.equals(a.getType())) { + throw new RSIllegalArgumentException("Types of allocations must match."); + } + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0); + } + + + /** * This is only intended to be used by auto-generate code reflected from the * renderscript script files. * @@ -794,44 +870,65 @@ public class Allocation extends BaseObj { } } - /** - * Copy a rectangular region from the array into the allocation. - * The incoming array is assumed to be tightly packed. - * - * @param xoff X offset of the region to update - * @param yoff Y offset of the region to update - * @param w Width of the incoming region to update - * @param h Height of the incoming region to update - * @param data to be placed into the allocation - */ - public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, byte[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length); } - public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length * 2); } - public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length * 4); } - public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length * 4); } + + /** + * Copy a rectangular region from the array into the allocation. + * The incoming array is assumed to be tightly packed. + * + * @param xoff X offset of the region to update + * @param yoff Y offset of the region to update + * @param w Width of the incoming region to update + * @param h Height of the incoming region to update + * @param data to be placed into the allocation + */ + public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { + validateIsInt8(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + } + + public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { + validateIsInt16(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + } + + public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { + validateIsInt32(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + } + + public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { + validateIsFloat32(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + } + /** * Copy a rectangular region into the allocation from another * allocation. @@ -865,6 +962,12 @@ public class Allocation extends BaseObj { */ public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) { mRS.validate(); + if (data.getConfig() == null) { + Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(newBitmap); + c.drawBitmap(data, 0, 0, null); + copy2DRangeFrom(xoff, yoff, newBitmap); + } validateBitmapFormat(data); validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); @@ -971,11 +1074,10 @@ public class Allocation extends BaseObj { * * A new type will be created with the new dimension. * - * @hide * @param dimX The new size of the allocation. * @param dimY The new size of the allocation. */ - public void resize(int dimX, int dimY) { + public synchronized void resize(int dimX, int dimY) { if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { throw new RSInvalidStateException( "Resize only support for 2D allocations at this time."); @@ -1135,8 +1237,36 @@ public class Allocation extends BaseObj { MipmapControl mips, int usage) { rs.validate(); + + // WAR undocumented color formats + if (b.getConfig() == null) { + if ((usage & USAGE_SHARED) != 0) { + throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config."); + } + Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(newBitmap); + c.drawBitmap(b, 0, 0, null); + return createFromBitmap(rs, newBitmap, mips, usage); + } + Type t = typeFromBitmap(rs, b, mips); + // enable optimized bitmap path only with no mipmap and script-only usage + if (mips == MipmapControl.MIPMAP_NONE && + t.getElement().isCompatible(Element.RGBA_8888(rs)) && + usage == (USAGE_SHARED | USAGE_SCRIPT)) { + int id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage); + if (id == 0) { + throw new RSRuntimeException("Load failed."); + } + + // keep a reference to the Bitmap around to prevent GC + Allocation alloc = new Allocation(id, rs, t, usage); + alloc.setBitmap(b); + return alloc; + } + + int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage); if (id == 0) { throw new RSRuntimeException("Load failed."); @@ -1145,33 +1275,25 @@ public class Allocation extends BaseObj { } /** + * For allocations used with io operations, returns the handle + * onto a raw buffer that is being managed by the screen + * compositor. * - * - * @hide + * @return Surface object associated with allocation * */ - public SurfaceTexture getSurfaceTexture() { + public Surface getSurface() { if ((mUsage & USAGE_IO_INPUT) == 0) { throw new RSInvalidStateException("Allocation is not a surface texture."); } - - int id = mRS.nAllocationGetSurfaceTextureID(getID(mRS)); - SurfaceTexture st = new SurfaceTexture(id); - mRS.nAllocationGetSurfaceTextureID2(getID(mRS), st); - - return st; + return mRS.nAllocationGetSurface(getID(mRS)); } /** - * For allocations used with io operations, returns the handle - * onto a raw buffer that is being managed by the screen - * compositor. - * - * @return Surface object associated with allocation - * + * @hide */ - public Surface getSurface() { - return new Surface(getSurfaceTexture()); + public void setSurfaceTexture(SurfaceTexture st) { + setSurface(new Surface(st)); } /** @@ -1189,21 +1311,11 @@ public class Allocation extends BaseObj { } /** - * @hide - */ - public void setSurfaceTexture(SurfaceTexture st) { - mRS.validate(); - if ((mUsage & USAGE_IO_OUTPUT) == 0) { - throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); - } - - Surface s = new Surface(st); - mRS.nAllocationSetSurface(getID(mRS), s); - } - - /** - * Creates a non-mipmapped renderscript allocation to use as a - * graphics texture + * Creates a RenderScript allocation from a bitmap. + * + * With target API version 18 or greater, this allocation will be + * created with USAGE_SHARED. With target API version 17 or lower, + * this allocation will be created with USAGE_GRAPHICS_TEXTURE. * * @param rs Context to which the allocation will belong. * @param b bitmap source for the allocation data @@ -1212,6 +1324,10 @@ public class Allocation extends BaseObj { * */ static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { + if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { + return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, + USAGE_SHARED | USAGE_SCRIPT); + } return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, USAGE_GRAPHICS_TEXTURE); } @@ -1411,6 +1527,10 @@ public class Allocation extends BaseObj { * Creates a non-mipmapped renderscript allocation to use as a * graphics texture from the bitmap referenced by resource id * + * With target API version 18 or greater, this allocation will be + * created with USAGE_SHARED. With target API version 17 or lower, + * this allocation will be created with USAGE_GRAPHICS_TEXTURE. + * * @param rs Context to which the allocation will belong. * @param res application resources * @param id resource id to load the data from @@ -1421,6 +1541,11 @@ public class Allocation extends BaseObj { static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id) { + if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { + return createFromBitmapResource(rs, res, id, + MipmapControl.MIPMAP_NONE, + USAGE_SHARED | USAGE_SCRIPT); + } return createFromBitmapResource(rs, res, id, MipmapControl.MIPMAP_NONE, USAGE_GRAPHICS_TEXTURE); |