diff options
Diffstat (limited to 'graphics/java')
15 files changed, 611 insertions, 340 deletions
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 7a4a1ca..e82ccd4 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -80,7 +80,6 @@ public class BitmapDrawable extends Drawable { @Deprecated public BitmapDrawable() { mBitmapState = new BitmapState((Bitmap) null); - mMutated = true; } /** @@ -91,7 +90,6 @@ public class BitmapDrawable extends Drawable { public BitmapDrawable(Resources res) { mBitmapState = new BitmapState((Bitmap) null); mBitmapState.mTargetDensity = mTargetDensity; - mMutated = true; } /** @@ -102,7 +100,6 @@ public class BitmapDrawable extends Drawable { @Deprecated public BitmapDrawable(Bitmap bitmap) { this(new BitmapState(bitmap), null); - mMutated = true; } /** @@ -112,7 +109,6 @@ public class BitmapDrawable extends Drawable { public BitmapDrawable(Resources res, Bitmap bitmap) { this(new BitmapState(bitmap), res); mBitmapState.mTargetDensity = mTargetDensity; - mMutated = true; } /** @@ -126,7 +122,6 @@ public class BitmapDrawable extends Drawable { if (mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); } - mMutated = true; } /** @@ -139,7 +134,6 @@ public class BitmapDrawable extends Drawable { if (mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); } - mMutated = true; } /** @@ -153,7 +147,6 @@ public class BitmapDrawable extends Drawable { if (mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); } - mMutated = true; } /** @@ -166,7 +159,6 @@ public class BitmapDrawable extends Drawable { if (mBitmap == null) { android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); } - mMutated = true; } /** @@ -560,7 +552,6 @@ public class BitmapDrawable extends Drawable { } else { mTargetDensity = state.mTargetDensity; } - mMutated = false; setBitmap(state != null ? state.mBitmap : null); } } diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index f8e3944..4561397 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -43,7 +43,6 @@ public class ColorDrawable extends Drawable { */ public ColorDrawable() { this(null); - mMutated = true; } /** @@ -54,7 +53,6 @@ public class ColorDrawable extends Drawable { public ColorDrawable(int color) { this(null); setColor(color); - mMutated = true; } private ColorDrawable(ColorState state) { diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 020a54f..f9392e4 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -37,7 +37,6 @@ import android.util.DisplayMetrics; import android.util.StateSet; import android.util.TypedValue; import android.util.Xml; -import android.view.View; import java.io.IOException; import java.io.InputStream; @@ -378,6 +377,8 @@ public abstract class Drawable { * * @return One of {@link android.view.View#LAYOUT_DIRECTION_LTR}, * {@link android.view.View#LAYOUT_DIRECTION_RTL} + * + * @hide */ public int getLayoutDirection() { return mLayoutDirection; @@ -388,8 +389,9 @@ public abstract class Drawable { * Drawable as no capacity to do the resolution on his own. * * @param layoutDirection One of {@link android.view.View#LAYOUT_DIRECTION_LTR}, - * {@link android.view.View#LAYOUT_DIRECTION_RTL}, + * {@link android.view.View#LAYOUT_DIRECTION_RTL} * + * @hide */ public void setLayoutDirection(int layoutDirection) { if (getLayoutDirection() != layoutDirection) { diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 486390c..41b272d 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -444,7 +444,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { int mConstantMinimumWidth; int mConstantMinimumHeight; - boolean mHaveOpacity = false; int mOpacity; boolean mHaveStateful = false; @@ -493,7 +492,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mConstantWidth = orig.mConstantWidth; mConstantHeight = orig.mConstantHeight; - mHaveOpacity = orig.mHaveOpacity; mOpacity = orig.mOpacity; mHaveStateful = orig.mHaveStateful; mStateful = orig.mStateful; @@ -528,7 +526,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mDrawables[pos] = dr; mNumChildren++; mChildrenChangingConfigurations |= dr.getChangingConfigurations(); - mHaveOpacity = false; mHaveStateful = false; mConstantPadding = null; @@ -656,10 +653,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } public final int getOpacity() { - if (mHaveOpacity) { - return mOpacity; - } - final int N = getChildCount(); final Drawable[] drawables = mDrawables; int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; @@ -667,7 +660,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); } mOpacity = op; - mHaveOpacity = true; return op; } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 21344f4..2ca54d4 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -124,7 +124,7 @@ public class GradientDrawable extends Drawable { private Paint mLayerPaint; // internal, used if we use saveLayer() private boolean mRectIsDirty; // internal state - private boolean mMutated = true; + private boolean mMutated; private Path mRingPath; private boolean mPathIsDirty = true; @@ -435,7 +435,8 @@ public class GradientDrawable extends Drawable { final int currFillAlpha = modulateAlpha(prevFillAlpha); final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha); - final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint.getStrokeWidth() > 0; + final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null && + mStrokePaint.getStrokeWidth() > 0; final boolean haveFill = currFillAlpha > 0; final GradientState st = mGradientState; /* we need a layer iff we're drawing both a fill and stroke, and the @@ -603,9 +604,9 @@ public class GradientDrawable extends Drawable { /** * <p>Changes this drawbale to use a single color instead of a gradient.</p> - * <p><strong>Note</strong>: changing orientation will affect all instances + * <p><strong>Note</strong>: changing color will affect all instances * of a drawable loaded from a resource. It is recommended to invoke - * {@link #mutate()} before changing the orientation.</p> + * {@link #mutate()} before changing the color.</p> * * @param argb The color used to fill the shape * @@ -649,7 +650,7 @@ public class GradientDrawable extends Drawable { @Override public int getOpacity() { - return PixelFormat.TRANSLUCENT; + return mGradientState.mOpaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT; } @Override @@ -1011,7 +1012,10 @@ public class GradientDrawable extends Drawable { } else { Log.w("drawable", "Bad element under <shape>: " + name); } + } + + mGradientState.computeOpacity(); } private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) { @@ -1079,10 +1083,11 @@ public class GradientDrawable extends Drawable { private float mGradientRadius = 0.5f; private boolean mUseLevel; private boolean mUseLevelForShape; + private boolean mOpaque; GradientState(Orientation orientation, int[] colors) { mOrientation = orientation; - mColors = colors; + setColors(colors); } public GradientState(GradientState state) { @@ -1120,6 +1125,7 @@ public class GradientDrawable extends Drawable { mGradientRadius = state.mGradientRadius; mUseLevel = state.mUseLevel; mUseLevelForShape = state.mUseLevelForShape; + mOpaque = state.mOpaque; } @Override @@ -1139,6 +1145,7 @@ public class GradientDrawable extends Drawable { public void setShape(int shape) { mShape = shape; + computeOpacity(); } public void setGradientType(int gradient) { @@ -1153,24 +1160,60 @@ public class GradientDrawable extends Drawable { public void setColors(int[] colors) { mHasSolidColor = false; mColors = colors; + computeOpacity(); } public void setSolidColor(int argb) { mHasSolidColor = true; mSolidColor = argb; mColors = null; + computeOpacity(); + } + + private void computeOpacity() { + if (mShape != RECTANGLE) { + mOpaque = false; + return; + } + + if (mStrokeWidth > 0 && !isOpaque(mStrokeColor)) { + mOpaque = false; + return; + } + + if (mHasSolidColor) { + mOpaque = isOpaque(mSolidColor); + return; + } + + if (mColors != null) { + for (int i = 0; i < mColors.length; i++) { + if (!isOpaque(mColors[i])) { + mOpaque = false; + return; + } + } + } + + mOpaque = true; + } + + private static boolean isOpaque(int color) { + return ((color >> 24) & 0xff) == 0xff; } public void setStroke(int width, int color) { mStrokeWidth = width; mStrokeColor = color; + computeOpacity(); } - + public void setStroke(int width, int color, float dashWidth, float dashGap) { mStrokeWidth = width; mStrokeColor = color; mStrokeDashWidth = dashWidth; mStrokeDashGap = dashGap; + computeOpacity(); } public void setCornerRadius(float radius) { @@ -1180,14 +1223,14 @@ public class GradientDrawable extends Drawable { mRadius = radius; mRadiusArray = null; } - + public void setCornerRadii(float[] radii) { mRadiusArray = radii; if (radii == null) { mRadius = 0; } } - + public void setSize(int width, int height) { mWidth = width; mHeight = height; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 7a43496..2ee6233 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -77,7 +77,6 @@ public class NinePatchDrawable extends Drawable { @Deprecated public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) { this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), null); - mMutated = true; } /** @@ -88,7 +87,6 @@ public class NinePatchDrawable extends Drawable { Rect padding, String srcName) { this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res); mNinePatchState.mTargetDensity = mTargetDensity; - mMutated = true; } /** @@ -101,7 +99,6 @@ public class NinePatchDrawable extends Drawable { Rect padding, Rect layoutInsets, String srcName) { this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding, layoutInsets), res); mNinePatchState.mTargetDensity = mTargetDensity; - mMutated = true; } /** @@ -112,7 +109,6 @@ public class NinePatchDrawable extends Drawable { @Deprecated public NinePatchDrawable(NinePatch patch) { this(new NinePatchState(patch, new Rect()), null); - mMutated = true; } /** @@ -122,7 +118,6 @@ public class NinePatchDrawable extends Drawable { public NinePatchDrawable(Resources res, NinePatch patch) { this(new NinePatchState(patch, new Rect()), res); mNinePatchState.mTargetDensity = mTargetDensity; - mMutated = true; } private void setNinePatchState(NinePatchState state, Resources res) { diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index af8b0c2..76edb0a 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -567,6 +567,42 @@ public class RenderScript { return rsnScriptIntrinsicCreate(mContext, id, eid); } + native int rsnScriptKernelIDCreate(int con, int sid, int slot, int sig); + synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) { + validate(); + return rsnScriptKernelIDCreate(mContext, sid, slot, sig); + } + + native int rsnScriptFieldIDCreate(int con, int sid, int slot); + synchronized int nScriptFieldIDCreate(int sid, int slot) { + validate(); + return rsnScriptFieldIDCreate(mContext, sid, slot); + } + + native int rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types); + synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) { + validate(); + return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types); + } + + native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc); + synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) { + validate(); + rsnScriptGroupSetInput(mContext, group, kernel, alloc); + } + + native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc); + synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) { + validate(); + rsnScriptGroupSetOutput(mContext, group, kernel, alloc); + } + + native void rsnScriptGroupExecute(int con, int group); + synchronized void nScriptGroupExecute(int group) { + validate(); + rsnScriptGroupExecute(mContext, group); + } + native int rsnSamplerCreate(int con, int magFilter, int minFilter, int wrapS, int wrapT, int wrapR, float aniso); synchronized int nSamplerCreate(int magFilter, int minFilter, diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java index bbf5e7e..3fe3261 100644 --- a/graphics/java/android/renderscript/Script.java +++ b/graphics/java/android/renderscript/Script.java @@ -16,10 +16,105 @@ package android.renderscript; +import android.util.SparseArray; + /** * **/ public class Script extends BaseObj { + + /** + * KernelID is an identifier for a Script + root function pair. It is used + * as an identifier for ScriptGroup creation. + * + * This class should not be directly created. Instead use the method in the + * reflected or intrinsic code "getKernelID_funcname()". + * + */ + public static final class KernelID extends BaseObj { + Script mScript; + int mSlot; + int mSig; + KernelID(int id, RenderScript rs, Script s, int slot, int sig) { + super(id, rs); + mScript = s; + mSlot = slot; + mSig = sig; + } + } + + private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>(); + /** + * Only to be used by generated reflected classes. + * + * + * @param slot + * @param sig + * @param ein + * @param eout + * + * @return KernelID + */ + protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) { + KernelID k = mKIDs.get(slot); + if (k != null) { + return k; + } + + int id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig); + if (id == 0) { + throw new RSDriverException("Failed to create KernelID"); + } + + k = new KernelID(id, mRS, this, slot, sig); + mKIDs.put(slot, k); + return k; + } + + /** + * FieldID is an identifier for a Script + exported field pair. It is used + * as an identifier for ScriptGroup creation. + * + * This class should not be directly created. Instead use the method in the + * reflected or intrinsic code "getFieldID_funcname()". + * + */ + public static final class FieldID extends BaseObj { + Script mScript; + int mSlot; + FieldID(int id, RenderScript rs, Script s, int slot) { + super(id, rs); + mScript = s; + mSlot = slot; + } + } + + private final SparseArray<FieldID> mFIDs = new SparseArray(); + /** + * Only to be used by generated reflected classes. + * + * @param slot + * @param e + * + * @return FieldID + */ + protected FieldID createFieldID(int slot, Element e) { + FieldID f = mFIDs.get(slot); + if (f != null) { + return f; + } + + int id = mRS.nScriptFieldIDCreate(getID(mRS), slot); + if (id == 0) { + throw new RSDriverException("Failed to create FieldID"); + } + + f = new FieldID(id, mRS, this, slot); + mFIDs.put(slot, f); + return f; + } + + /** * Only intended for use by generated reflected code. * diff --git a/graphics/java/android/renderscript/ScriptGroup.java b/graphics/java/android/renderscript/ScriptGroup.java index c4064b5..4efb45b 100644 --- a/graphics/java/android/renderscript/ScriptGroup.java +++ b/graphics/java/android/renderscript/ScriptGroup.java @@ -17,67 +17,60 @@ package android.renderscript; import java.lang.reflect.Method; +import java.util.ArrayList; /** - * @hide + * ScriptGroup creates a groups of scripts which are executed + * together based upon upon one execution call as if they were + * all part of a single script. The scripts may be connected + * internally or to an external allocation. For the internal + * connections the intermediate results are not observable after + * the execution of the script. + * <p> + * The external connections are grouped into inputs and outputs. + * All outputs are produced by a script kernel and placed into a + * user supplied allocation. Inputs are similar but supply the + * input of a kernal. Inputs bounds to a script are set directly + * upon the script. + * **/ -public class ScriptGroup extends BaseObj { - Node mNodes[]; - Connection mConnections[]; - Node mFirstNode; +public final class ScriptGroup extends BaseObj { IO mOutputs[]; IO mInputs[]; static class IO { - Script mScript; + Script.KernelID mKID; Allocation mAllocation; - String mName; - IO(Script s) { - mScript = s; - } - IO(Script s, String n) { - mScript = s; - mName = n; + IO(Script.KernelID s) { + mKID = s; } } - static class Connection { - Node mTo[]; - String mToName[]; - Node mFrom; - Type mAllocationType; - Allocation mInternalAllocation; - - Connection(Node out, Type t) { - mFrom = out; + static class ConnectLine { + ConnectLine(Type t, Script.KernelID from, Script.KernelID to) { + mFrom = from; + mToK = to; mAllocationType = t; } - void addTo(Node n, String name) { - if (mTo == null) { - mTo = new Node[1]; - mToName = new String[1]; - } else { - Node nt[] = new Node[mTo.length + 1]; - String ns[] = new String[mTo.length + 1]; - System.arraycopy(mTo, 0, nt, 0, mTo.length); - System.arraycopy(mToName, 0, ns, 0, mTo.length); - mTo = nt; - mToName = ns; - } - mTo[mTo.length - 1] = n; - mToName[mTo.length - 1] = name; + ConnectLine(Type t, Script.KernelID from, Script.FieldID to) { + mFrom = from; + mToF = to; + mAllocationType = t; } + + Script.FieldID mToF; + Script.KernelID mToK; + Script.KernelID mFrom; + Type mAllocationType; } static class Node { Script mScript; - Connection mInput[] = new Connection[8]; - Connection mOutput[] = new Connection[1]; - int mInputCount; - int mOutputCount; - int mDepth; + ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>(); + ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>(); + ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>(); boolean mSeen; Node mNext; @@ -85,24 +78,6 @@ public class ScriptGroup extends BaseObj { Node(Script s) { mScript = s; } - - void addInput(Connection c) { - if (mInput.length <= mInputCount) { - Connection[] nc = new Connection[mInput.length + 8]; - System.arraycopy(mInput, 0, nc, 0, mInputCount); - mInput = nc; - } - mInput[mInputCount++] = c; - } - - void addOutput(Connection c) { - if (mOutput.length <= mOutputCount) { - Connection[] nc = new Connection[mOutput.length + 8]; - System.arraycopy(mOutput, 0, nc, 0, mOutputCount); - mOutput = nc; - } - mOutput[mOutputCount++] = c; - } } @@ -110,276 +85,326 @@ public class ScriptGroup extends BaseObj { super(id, rs); } - void init(int nodeCount, int connectionCount) { - mNodes = new Node[nodeCount]; - mConnections = new Connection[connectionCount]; - - android.util.Log.v("RSR", "init" + nodeCount + ", " + connectionCount); - - // Count outputs and create array. - Node n = mFirstNode; - int outputCount = 0; - int inputCount = 0; - int connectionIndex = 0; - int nodeNum = 0; - while (n != null) { - mNodes[nodeNum++] = n; - - // Look for unattached kernel inputs - boolean hasInput = false; - for (int ct=0; ct < n.mInput.length; ct++) { - if (n.mInput[ct] != null) { - if (n.mInput[ct].mToName == null) { - hasInput = true; - } - } - } - if (!hasInput) { - if (mInputs == null) { - mInputs = new IO[1]; - } - if (mInputs.length <= inputCount) { - IO t[] = new IO[mInputs.length + 1]; - System.arraycopy(mInputs, 0, t, 0, mInputs.length); - mInputs = t; - } - mInputs[inputCount++] = new IO(n.mScript); - } - - // Look for unattached kernel outputs - boolean hasOutput = false; - for (int ct=0; ct < n.mOutput.length; ct++) { - if (n.mOutput[ct] != null) { - hasOutput = true; - } - } - if (!hasOutput) { - if (mOutputs == null) { - mOutputs = new IO[1]; - } - if (mOutputs.length <= outputCount) { - IO t[] = new IO[mOutputs.length + 1]; - System.arraycopy(mOutputs, 0, t, 0, mOutputs.length); - mOutputs = t; - } - mOutputs[outputCount++] = new IO(n.mScript); - } - - // Make allocations for internal connections - // Since script outputs are unique, use those to avoid duplicates. - for (int ct=0; ct < n.mOutput.length; ct++) { - android.util.Log.v("RSR", "init out2 " + n.mOutput[ct]); - if (n.mOutput[ct] != null) { - Connection t = n.mOutput[ct]; - mConnections[connectionIndex++] = t; - t.mInternalAllocation = Allocation.createTyped(mRS, t.mAllocationType); - } - } - - n = n.mNext; - } - } - - public void setInput(Script s, Allocation a) { + /** + * Sets an input of the ScriptGroup. This specifies an + * Allocation to be used for the kernels which require a kernel + * input and that input is provided external to the group. + * + * @param s The ID of the kernel where the allocation should be + * connected. + * @param a The allocation to connect. + */ + public void setInput(Script.KernelID s, Allocation a) { for (int ct=0; ct < mInputs.length; ct++) { - if (mInputs[ct].mScript == s) { + if (mInputs[ct].mKID == s) { mInputs[ct].mAllocation = a; + mRS.nScriptGroupSetInput(getID(mRS), s.getID(mRS), mRS.safeID(a)); return; } } throw new RSIllegalArgumentException("Script not found"); } - public void setOutput(Script s, Allocation a) { + /** + * Sets an output of the ScriptGroup. This specifies an + * Allocation to be used for the kernels which require a kernel + * output and that output is provided external to the group. + * + * @param s The ID of the kernel where the allocation should be + * connected. + * @param a The allocation to connect. + */ + public void setOutput(Script.KernelID s, Allocation a) { for (int ct=0; ct < mOutputs.length; ct++) { - if (mOutputs[ct].mScript == s) { + if (mOutputs[ct].mKID == s) { mOutputs[ct].mAllocation = a; + mRS.nScriptGroupSetOutput(getID(mRS), s.getID(mRS), mRS.safeID(a)); return; } } throw new RSIllegalArgumentException("Script not found"); } + /** + * Execute the ScriptGroup. This will run all the kernels in + * the script. The state of the connecting lines will not be + * observable after this operation. + */ public void execute() { - android.util.Log.v("RSR", "execute"); - boolean more = true; - int depth = 0; - while (more) { - more = false; - for (int ct=0; ct < mNodes.length; ct++) { - if (mNodes[ct].mDepth == depth) { - more = true; - - Allocation kernelIn = null; - for (int ct2=0; ct2 < mNodes[ct].mInputCount; ct2++) { - android.util.Log.v("RSR", " kin " + ct2 + ", to " + mNodes[ct].mInput[ct2].mTo[0] + ", name " + mNodes[ct].mInput[ct2].mToName[0]); - if (mNodes[ct].mInput[ct2].mToName[0] == null) { - kernelIn = mNodes[ct].mInput[ct2].mInternalAllocation; - break; - } - } - - Allocation kernelOut= null; - for (int ct2=0; ct2 < mNodes[ct].mOutputCount; ct2++) { - android.util.Log.v("RSR", " kout " + ct2 + ", from " + mNodes[ct].mOutput[ct2].mFrom); - if (mNodes[ct].mOutput[ct2].mFrom != null) { - kernelOut = mNodes[ct].mOutput[ct2].mInternalAllocation; - break; - } - } - if (kernelOut == null) { - for (int ct2=0; ct2 < mOutputs.length; ct2++) { - if (mOutputs[ct2].mScript == mNodes[ct].mScript) { - kernelOut = mOutputs[ct2].mAllocation; - break; - } - } - } - - android.util.Log.v("RSR", "execute calling " + mNodes[ct] + ", with " + kernelIn); - if (kernelIn != null) { - try { - - Method m = mNodes[ct].mScript.getClass().getMethod("forEach_root", - new Class[] { Allocation.class, Allocation.class }); - m.invoke(mNodes[ct].mScript, new Object[] {kernelIn, kernelOut} ); - } catch (Throwable t) { - android.util.Log.e("RSR", "execute error " + t); - } - } else { - try { - Method m = mNodes[ct].mScript.getClass().getMethod("forEach_root", - new Class[] { Allocation.class }); - m.invoke(mNodes[ct].mScript, new Object[] {kernelOut} ); - } catch (Throwable t) { - android.util.Log.e("RSR", "execute error " + t); - } - } - - } - } - depth ++; - } - + mRS.nScriptGroupExecute(getID(mRS)); } - public static class Builder { - RenderScript mRS; - Node mFirstNode; - int mConnectionCount = 0; - int mNodeCount = 0; - + /** + * Create a ScriptGroup. There are two steps to creating a + * ScriptGoup. + * <p> + * First all the Kernels to be used by the group should be + * added. Once this is done the kernels should be connected. + * Kernels cannot be added once a connection has been made. + * <p> + * Second, add connections. There are two forms of connections. + * Kernel to Kernel and Kernel to Field. Kernel to Kernel is + * higher performance and should be used where possible. The + * line of connections cannot form a loop. If a loop is detected + * an exception is thrown. + * <p> + * Once all the connections are made a call to create will + * return the ScriptGroup object. + * + */ + public static final class Builder { + private RenderScript mRS; + private ArrayList<Node> mNodes = new ArrayList<Node>(); + private ArrayList<ConnectLine> mLines = new ArrayList<ConnectLine>(); + private int mKernelCount; + + /** + * Create a builder for generating a ScriptGroup. + * + * + * @param rs The Renderscript context. + */ public Builder(RenderScript rs) { mRS = rs; } private void validateRecurse(Node n, int depth) { n.mSeen = true; - if (depth > n.mDepth) { - n.mDepth = depth; - } - android.util.Log.v("RSR", " validateRecurse outputCount " + n.mOutputCount); - for (int ct=0; ct < n.mOutputCount; ct++) { - for (int ct2=0; ct2 < n.mOutput[ct].mTo.length; ct2++) { - if (n.mOutput[ct].mTo[ct2].mSeen) { + //android.util.Log.v("RSR", " validateRecurse outputCount " + n.mOutputs.size()); + for (int ct=0; ct < n.mOutputs.size(); ct++) { + final ConnectLine cl = n.mOutputs.get(ct); + if (cl.mToK != null) { + Node tn = findNode(cl.mToK.mScript); + if (tn.mSeen) { throw new RSInvalidStateException("Loops in group not allowed."); } - validateRecurse(n.mOutput[ct].mTo[ct2], depth + 1); + validateRecurse(tn, depth + 1); + } + if (cl.mToF != null) { + Node tn = findNode(cl.mToF.mScript); + if (tn.mSeen) { + throw new RSInvalidStateException("Loops in group not allowed."); + } + validateRecurse(tn, depth + 1); } } } private void validate() { - android.util.Log.v("RSR", "validate"); - Node n = mFirstNode; - while (n != null) { - n.mSeen = false; - n.mDepth = 0; - n = n.mNext; - } + //android.util.Log.v("RSR", "validate"); - n = mFirstNode; - while (n != null) { - android.util.Log.v("RSR", "validate n= " + n); - if ((n.mSeen == false) && (n.mInputCount == 0)) { - android.util.Log.v("RSR", " recursing " + n); + for (int ct=0; ct < mNodes.size(); ct++) { + for (int ct2=0; ct2 < mNodes.size(); ct2++) { + mNodes.get(ct2).mSeen = false; + } + Node n = mNodes.get(ct); + if (n.mInputs.size() == 0) { validateRecurse(n, 0); } - n = n.mNext; } } - private Node findScript(Script s) { - Node n = mFirstNode; - while (n != null) { - if (n.mScript == s) { - return n; + private Node findNode(Script s) { + for (int ct=0; ct < mNodes.size(); ct++) { + if (s == mNodes.get(ct).mScript) { + return mNodes.get(ct); } - n = n.mNext; } return null; } - private void addNode(Node n) { - n.mNext = mFirstNode; - mFirstNode = n; - } - - public Builder addConnection(Type t, Script output, Script input, String inputName) { - android.util.Log.v("RSR", "addConnection " + t +", " + output + ", " + input); - - // Look for existing output - Node nout = findScript(output); - Connection c; - if (nout == null) { - // Make new node - android.util.Log.v("RSR", "addConnection new output node"); - nout = new Node(output); - mNodeCount++; - c = new Connection(nout, t); - mConnectionCount++; - nout.addOutput(c); - addNode(nout); - } else { - // Add to existing node - android.util.Log.v("RSR", "addConnection reuse output node"); - if (nout.mOutput[0] != null) { - if (nout.mOutput[0].mFrom.mScript != output) { - throw new RSInvalidStateException("Changed output of existing node"); - } - if (nout.mOutput[0].mAllocationType != t) { - throw new RSInvalidStateException("Changed output type of existing node"); + private Node findNode(Script.KernelID k) { + for (int ct=0; ct < mNodes.size(); ct++) { + Node n = mNodes.get(ct); + for (int ct2=0; ct2 < n.mKernels.size(); ct2++) { + if (k == n.mKernels.get(ct2)) { + return n; } } - c = nout.mOutput[0]; } - // At this point we should have a connection attached to a script ouput. - - // Find input - Node nin = findScript(input); - if (nin == null) { - android.util.Log.v("RSR", "addConnection new input node"); - nin = new Node(input); - mNodeCount++; - addNode(nin); + return null; + } + + /** + * Adds a Kernel to the group. + * + * + * @param k The kernel to add. + * + * @return Builder Returns this. + */ + public Builder addKernel(Script.KernelID k) { + if (mLines.size() != 0) { + throw new RSInvalidStateException( + "Kernels may not be added once connections exist."); + } + + //android.util.Log.v("RSR", "addKernel 1 k=" + k); + if (findNode(k) != null) { + return this; + } + //android.util.Log.v("RSR", "addKernel 2 "); + mKernelCount++; + Node n = findNode(k.mScript); + if (n == null) { + //android.util.Log.v("RSR", "addKernel 3 "); + n = new Node(k.mScript); + mNodes.add(n); + } + n.mKernels.add(k); + return this; + } + + /** + * Adds a connection to the group. + * + * + * @param t The type of the connection. This is used to + * determine the kernel launch sizes on the source side + * of this connection. + * @param from The source for the connection. + * @param to The destination of the connection. + * + * @return Builder Returns this + */ + public Builder addConnection(Type t, Script.KernelID from, Script.FieldID to) { + //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to); + + Node nf = findNode(from); + if (nf == null) { + throw new RSInvalidStateException("From kernel not found."); + } + + Node nt = findNode(to.mScript); + if (nt == null) { + throw new RSInvalidStateException("To script not found."); + } + + ConnectLine cl = new ConnectLine(t, from, to); + mLines.add(new ConnectLine(t, from, to)); + + nf.mOutputs.add(cl); + nt.mInputs.add(cl); + + validate(); + return this; + } + + /** + * Adds a connection to the group. + * + * + * @param t The type of the connection. This is used to + * determine the kernel launch sizes for both sides of + * this connection. + * @param from The source for the connection. + * @param to The destination of the connection. + * + * @return Builder Returns this + */ + public Builder addConnection(Type t, Script.KernelID from, Script.KernelID to) { + //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to); + + Node nf = findNode(from); + if (nf == null) { + throw new RSInvalidStateException("From kernel not found."); + } + + Node nt = findNode(to); + if (nt == null) { + throw new RSInvalidStateException("To script not found."); } - c.addTo(nin, inputName); - nin.addInput(c); + + ConnectLine cl = new ConnectLine(t, from, to); + mLines.add(new ConnectLine(t, from, to)); + + nf.mOutputs.add(cl); + nt.mInputs.add(cl); validate(); return this; } + + + /** + * Creates the Script group. + * + * + * @return ScriptGroup The new ScriptGroup + */ public ScriptGroup create() { - ScriptGroup sg = new ScriptGroup(0, mRS); - sg.mFirstNode = mFirstNode; - mFirstNode = null; + ArrayList<IO> inputs = new ArrayList<IO>(); + ArrayList<IO> outputs = new ArrayList<IO>(); + + int[] kernels = new int[mKernelCount]; + int idx = 0; + for (int ct=0; ct < mNodes.size(); ct++) { + Node n = mNodes.get(ct); + for (int ct2=0; ct2 < n.mKernels.size(); ct2++) { + final Script.KernelID kid = n.mKernels.get(ct2); + kernels[idx++] = kid.getID(mRS); + + boolean hasInput = false; + boolean hasOutput = false; + for (int ct3=0; ct3 < n.mInputs.size(); ct3++) { + if (n.mInputs.get(ct3).mToK == kid) { + hasInput = true; + } + } + for (int ct3=0; ct3 < n.mOutputs.size(); ct3++) { + if (n.mOutputs.get(ct3).mFrom == kid) { + hasOutput = true; + } + } + if (!hasInput) { + inputs.add(new IO(kid)); + } + if (!hasOutput) { + outputs.add(new IO(kid)); + } - android.util.Log.v("RSR", "create nodes= " + mNodeCount + ", Connections= " + mConnectionCount); + } + } + if (idx != mKernelCount) { + throw new RSRuntimeException("Count mismatch, should not happen."); + } + + int[] src = new int[mLines.size()]; + int[] dstk = new int[mLines.size()]; + int[] dstf = new int[mLines.size()]; + int[] types = new int[mLines.size()]; + + for (int ct=0; ct < mLines.size(); ct++) { + ConnectLine cl = mLines.get(ct); + src[ct] = cl.mFrom.getID(mRS); + if (cl.mToK != null) { + dstk[ct] = cl.mToK.getID(mRS); + } + if (cl.mToF != null) { + dstf[ct] = cl.mToF.getID(mRS); + } + types[ct] = cl.mAllocationType.getID(mRS); + } + + int id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types); + if (id == 0) { + throw new RSRuntimeException("Object creation error, should not happen."); + } + + ScriptGroup sg = new ScriptGroup(id, mRS); + sg.mOutputs = new IO[outputs.size()]; + for (int ct=0; ct < outputs.size(); ct++) { + sg.mOutputs[ct] = outputs.get(ct); + } + + sg.mInputs = new IO[inputs.size()]; + for (int ct=0; ct < inputs.size(); ct++) { + sg.mInputs[ct] = inputs.get(ct); + } - sg.init(mNodeCount, mConnectionCount); return sg; } diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java index 8d093a7..61e5d4f 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java @@ -91,5 +91,22 @@ public final class ScriptIntrinsicBlur extends ScriptIntrinsic { forEach(0, null, aout, null); } + /** + * Get a KernelID for this intrinsic kernel. + * + * @return Script.KernelID The KernelID object. + */ + public Script.KernelID getKernelID() { + return createKernelID(0, 2, null, null); + } + + /** + * Get a FieldID for the input field of this intrinsic. + * + * @return Script.FieldID The FieldID object. + */ + public Script.FieldID getFieldID_Input() { + return createFieldID(1, null); + } } diff --git a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java index 933a4dd..cb458ba 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java @@ -154,5 +154,14 @@ public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic { forEach(0, ain, aout, null); } + /** + * Get a KernelID for this intrinsic kernel. + * + * @return Script.KernelID The KernelID object. + */ + public Script.KernelID getKernelID() { + return createKernelID(0, 3, null, null); + } + } diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java index fb2948d..d7e9f32 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java @@ -103,5 +103,23 @@ public final class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic { forEach(0, null, aout, null); } + /** + * Get a KernelID for this intrinsic kernel. + * + * @return Script.KernelID The KernelID object. + */ + public Script.KernelID getKernelID() { + return createKernelID(0, 2, null, null); + } + + /** + * Get a FieldID for the input field of this intrinsic. + * + * @return Script.FieldID The FieldID object. + */ + public Script.FieldID getFieldID_Input() { + return createFieldID(1, null); + } + } diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java index 8599426..ff31270 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java @@ -98,5 +98,22 @@ public final class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic { forEach(0, null, aout, null); } + /** + * Get a KernelID for this intrinsic kernel. + * + * @return Script.KernelID The KernelID object. + */ + public Script.KernelID getKernelID() { + return createKernelID(0, 2, null, null); + } + + /** + * Get a FieldID for the input field of this intrinsic. + * + * @return Script.FieldID The FieldID object. + */ + public Script.FieldID getFieldID_Input() { + return createFieldID(1, null); + } } diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java index e45c0fd..188e04c 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java @@ -134,5 +134,13 @@ public final class ScriptIntrinsicLUT extends ScriptIntrinsic { forEach(0, ain, aout, null); } + /** + * Get a KernelID for this intrinsic kernel. + * + * @return Script.KernelID The KernelID object. + */ + public Script.KernelID getKernelID() { + return createKernelID(0, 3, null, null); + } } diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java index b4a228b..415061c 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java @@ -16,49 +16,74 @@ package android.renderscript; -import android.content.Context; -import android.content.res.Resources; -import android.util.Log; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map.Entry; -import java.util.HashMap; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; /** - * @hide - **/ -public class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic { + * Intrinsic for converting an Android YUV buffer to RGB. + * + * The input allocation is supplied in NV21 format as a U8 + * element type. The output is RGBA, the alpha channel will be + * set to 255. + */ +public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic { + private Allocation mInput; + ScriptIntrinsicYuvToRGB(int id, RenderScript rs) { super(id, rs); } + /** + * Create an intrinsic for converting YUV to RGB. + * + * Supported elements types are {@link Element#U8_4} + * + * @param rs The Renderscript context + * @param e Element type for output + * + * @return ScriptIntrinsicYuvToRGB + */ + public static ScriptIntrinsicYuvToRGB create(RenderScript rs, Element e) { + // 6 comes from RS_SCRIPT_INTRINSIC_YUV_TO_RGB in rsDefines.h + int id = rs.nScriptIntrinsicCreate(6, e.getID(rs)); + ScriptIntrinsicYuvToRGB si = new ScriptIntrinsicYuvToRGB(id, rs); + return si; + } - public static class Builder { - RenderScript mRS; - - public Builder(RenderScript rs) { - mRS = rs; - } - - public void setInputFormat(int inputFormat) { - - } - - public void setOutputFormat(Element e) { - - } - - public ScriptIntrinsicYuvToRGB create() { - return null; + /** + * Set the input yuv allocation, must be {@link Element#U8}. + * + * @param ain The input allocation. + */ + public void setInput(Allocation ain) { + mInput = ain; + bindAllocation(ain, 0); + } - } + /** + * Convert the image to RGB. + * + * @param aout Output allocation. Must match creation element + * type. + */ + public void forEach(Allocation aout) { + forEach(0, null, aout, null); + } + /** + * Get a KernelID for this intrinsic kernel. + * + * @return Script.KernelID The KernelID object. + */ + public Script.KernelID getKernelID() { + return createKernelID(0, 2, null, null); } + /** + * Get a FieldID for the input field of this intrinsic. + * + * @return Script.FieldID The FieldID object. + */ + public Script.FieldID getFieldID_Input() { + return createFieldID(0, null); + } } |
