diff options
| author | Ricardo Cerqueira <ricardo@cyngn.com> | 2015-03-10 12:15:08 +0000 |
|---|---|---|
| committer | Ricardo Cerqueira <ricardo@cyngn.com> | 2015-03-10 12:15:08 +0000 |
| commit | 4d9245fd508125ca177794b7eb740dbcf35a1366 (patch) | |
| tree | 016c49a6d577cdfe83fe317bdf30274a43923199 | |
| parent | b0a4a7f403287d16ade9451722a50b4cb00723f1 (diff) | |
| parent | ad410d91de8f32e02f824c40b58db638dcafc1b4 (diff) | |
| download | android_frameworks_rs-cm-12.1.tar.gz android_frameworks_rs-cm-12.1.tar.bz2 android_frameworks_rs-cm-12.1.zip | |
Merge tag 'android-5.1.0_r1' into HEADstaging/cm-12.1stable/cm-12.1-YOG7Dstable/cm-12.1-YOG4Pstable/cm-12.1-YOG3Ccm-12.1
Android 5.1.0 release 1
60 files changed, 1707 insertions, 746 deletions
diff --git a/cpu_ref/Android.mk b/cpu_ref/Android.mk index bd276bf2..f041ad96 100644 --- a/cpu_ref/Android.mk +++ b/cpu_ref/Android.mk @@ -42,6 +42,10 @@ LOCAL_SRC_FILES:= \ LOCAL_CFLAGS_arm64 += -DARCH_ARM_USE_INTRINSICS -DARCH_ARM64_USE_INTRINSICS -DARCH_ARM64_HAVE_NEON +ifeq ($(RS_DISABLE_A53_WORKAROUND),true) +LOCAL_CFLAGS_arm64 += -DDISABLE_A53_WORKAROUND +endif + LOCAL_SRC_FILES_arm64 += \ rsCpuIntrinsics_advsimd_3DLUT.S \ rsCpuIntrinsics_advsimd_Convolve.S \ diff --git a/cpu_ref/rsCpuCore.cpp b/cpu_ref/rsCpuCore.cpp index f09e3342..4285dae5 100644 --- a/cpu_ref/rsCpuCore.cpp +++ b/cpu_ref/rsCpuCore.cpp @@ -266,7 +266,7 @@ bool RsdCpuReferenceImpl::init(uint32_t version_major, uint32_t version_minor, GetCpuInfo(); - int cpu = sysconf(_SC_NPROCESSORS_ONLN); + int cpu = sysconf(_SC_NPROCESSORS_CONF); if(mRSC->props.mDebugMaxThreads) { cpu = mRSC->props.mDebugMaxThreads; } diff --git a/cpu_ref/rsCpuIntrinsicBlur.cpp b/cpu_ref/rsCpuIntrinsicBlur.cpp index 123cc9f6..9dccd80d 100644 --- a/cpu_ref/rsCpuIntrinsicBlur.cpp +++ b/cpu_ref/rsCpuIntrinsicBlur.cpp @@ -297,7 +297,7 @@ void RsdCpuScriptIntrinsicBlur::kernelU4(const RsForEachStubParamStruct *p, uint32_t x2 = xend; #if defined(ARCH_ARM_USE_INTRINSICS) - if (gArchUseSIMD && !xstart && (xend == p->dimX)) { + if (gArchUseSIMD) { rsdIntrinsicBlurU4_K(out, (uchar4 const *)(pin + stride * p->y), p->dimX, p->dimY, stride, x1, p->y, x2 - x1, cp->mIradius, cp->mIp + cp->mIradius); return; @@ -367,9 +367,9 @@ void RsdCpuScriptIntrinsicBlur::kernelU1(const RsForEachStubParamStruct *p, uint32_t x2 = xend; #if defined(ARCH_ARM_USE_INTRINSICS) - if (gArchUseSIMD && !xstart && (xend == p->dimX)) { + if (gArchUseSIMD) { rsdIntrinsicBlurU1_K(out, pin + stride * p->y, p->dimX, p->dimY, - stride, 0, p->y, p->dimX, cp->mIradius, cp->mIp + cp->mIradius); + stride, x1, p->y, x2 - x1, cp->mIradius, cp->mIp + cp->mIradius); return; } #endif diff --git a/cpu_ref/rsCpuIntrinsicColorMatrix.cpp b/cpu_ref/rsCpuIntrinsicColorMatrix.cpp index 8c852778..6a7808e7 100644 --- a/cpu_ref/rsCpuIntrinsicColorMatrix.cpp +++ b/cpu_ref/rsCpuIntrinsicColorMatrix.cpp @@ -126,7 +126,7 @@ typedef union { } Key_t; //Re-enable when intrinsic is fixed -#if 0 && defined(ARCH_ARM64_USE_INTRINSICS) +#if defined(ARCH_ARM64_USE_INTRINSICS) typedef struct { void (*column[4])(void); void (*store)(void); @@ -184,7 +184,7 @@ protected: int ipa[4]; float tmpFp[16]; float tmpFpa[4]; -#if 0 && defined(ARCH_ARM64_USE_INTRINSICS) +#if defined(ARCH_ARM64_USE_INTRINSICS) FunctionTab_t mFnTab; #endif @@ -910,16 +910,20 @@ void RsdCpuScriptIntrinsicColorMatrix::kernel(const RsForEachStubParamStruct *p, out += outstep * len; in += instep * len; } -#if 0 && defined(ARCH_ARM64_USE_INTRINSICS) +#if defined(ARCH_ARM64_USE_INTRINSICS) else { if (cp->mLastKey.u.inType == RS_TYPE_FLOAT_32 || cp->mLastKey.u.outType == RS_TYPE_FLOAT_32) { - rsdIntrinsicColorMatrix_float_K(out, in, len, &cp->mFnTab, cp->tmpFp, cp->tmpFpa); + // Currently this generates off by one errors. + //rsdIntrinsicColorMatrix_float_K(out, in, len, &cp->mFnTab, cp->tmpFp, cp->tmpFpa); + //x1 += len; + //out += outstep * len; + //in += instep * len; } else { rsdIntrinsicColorMatrix_int_K(out, in, len, &cp->mFnTab, cp->ip, cp->ipa); + x1 += len; + out += outstep * len; + in += instep * len; } - x1 += len; - out += outstep * len; - in += instep * len; } #endif } @@ -971,7 +975,7 @@ void RsdCpuScriptIntrinsicColorMatrix::preLaunch( if (build(key)) { mOptKernel = (void (*)(void *, const void *, const short *, uint32_t)) mBuf; } -#if 0 && defined(ARCH_ARM64_USE_INTRINSICS) +#if defined(ARCH_ARM64_USE_INTRINSICS) else { int dt = key.u.outVecSize + (key.u.outType == RS_TYPE_FLOAT_32 ? 4 : 0); int st = key.u.inVecSize + (key.u.inType == RS_TYPE_FLOAT_32 ? 4 : 0); diff --git a/cpu_ref/rsCpuIntrinsicConvolve3x3.cpp b/cpu_ref/rsCpuIntrinsicConvolve3x3.cpp index 552a8353..e5953cf3 100644 --- a/cpu_ref/rsCpuIntrinsicConvolve3x3.cpp +++ b/cpu_ref/rsCpuIntrinsicConvolve3x3.cpp @@ -105,7 +105,7 @@ static void ConvolveOneU4(const RsForEachStubParamStruct *p, uint32_t x, uchar4 convert_float4(py2[x]) * coeff[7] + convert_float4(py2[x2]) * coeff[8]; - px = clamp(px, 0.f, 255.f); + px = clamp(px + 0.5f, 0.f, 255.f); uchar4 o = {(uchar)px.x, (uchar)px.y, (uchar)px.z, (uchar)px.w}; *out = o; } @@ -127,7 +127,7 @@ static void ConvolveOneU2(const RsForEachStubParamStruct *p, uint32_t x, uchar2 convert_float2(py2[x]) * coeff[7] + convert_float2(py2[x2]) * coeff[8]; - px = clamp(px, 0.f, 255.f); + px = clamp(px + 0.5f, 0.f, 255.f); *out = convert_uchar2(px); } @@ -147,7 +147,7 @@ static void ConvolveOneU1(const RsForEachStubParamStruct *p, uint32_t x, uchar * ((float)py2[x1]) * coeff[6] + ((float)py2[x]) * coeff[7] + ((float)py2[x2]) * coeff[8]; - *out = clamp(px, 0.f, 255.f); + *out = clamp(px + 0.5f, 0.f, 255.f); } static void ConvolveOneF4(const RsForEachStubParamStruct *p, uint32_t x, float4 *out, diff --git a/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp b/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp index e2a6b8b1..a2c29fd3 100644 --- a/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp +++ b/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp @@ -125,7 +125,7 @@ static void OneU4(const RsForEachStubParamStruct *p, uint32_t x, uchar4 *out, convert_float4(py4[x2]) * coeff[22] + convert_float4(py4[x3]) * coeff[23] + convert_float4(py4[x4]) * coeff[24]; - px = clamp(px, 0.f, 255.f); + px = clamp(px + 0.5f, 0.f, 255.f); *out = convert_uchar4(px); } @@ -168,7 +168,7 @@ static void OneU2(const RsForEachStubParamStruct *p, uint32_t x, uchar2 *out, convert_float2(py4[x2]) * coeff[22] + convert_float2(py4[x3]) * coeff[23] + convert_float2(py4[x4]) * coeff[24]; - px = clamp(px, 0.f, 255.f); + px = clamp(px + 0.5f, 0.f, 255.f); *out = convert_uchar2(px); } @@ -211,7 +211,7 @@ static void OneU1(const RsForEachStubParamStruct *p, uint32_t x, uchar *out, (float)(py4[x2]) * coeff[22] + (float)(py4[x3]) * coeff[23] + (float)(py4[x4]) * coeff[24]; - px = clamp(px, 0.f, 255.f); + px = clamp(px + 0.5f, 0.f, 255.f); *out = px; } diff --git a/cpu_ref/rsCpuIntrinsicResize.cpp b/cpu_ref/rsCpuIntrinsicResize.cpp index 474f82d1..19607c97 100644 --- a/cpu_ref/rsCpuIntrinsicResize.cpp +++ b/cpu_ref/rsCpuIntrinsicResize.cpp @@ -83,7 +83,7 @@ static float cubicInterpolate(float p0,float p1,float p2,float p3 , float x) { static uchar4 OneBiCubic(const uchar4 *yp0, const uchar4 *yp1, const uchar4 *yp2, const uchar4 *yp3, float xf, float yf, int width) { - int startx = (int) floor(xf - 2); + int startx = (int) floor(xf - 1); xf = xf - floor(xf); int maxx = width - 1; int xs0 = rsMax(0, startx + 0); @@ -112,13 +112,13 @@ static uchar4 OneBiCubic(const uchar4 *yp0, const uchar4 *yp1, const uchar4 *yp2 convert_float4(yp3[xs3]), xf); float4 p = cubicInterpolate(p0, p1, p2, p3, yf); - p = clamp(p, 0.f, 255.f); + p = clamp(p + 0.5f, 0.f, 255.f); return convert_uchar4(p); } static uchar2 OneBiCubic(const uchar2 *yp0, const uchar2 *yp1, const uchar2 *yp2, const uchar2 *yp3, float xf, float yf, int width) { - int startx = (int) floor(xf - 2); + int startx = (int) floor(xf - 1); xf = xf - floor(xf); int maxx = width - 1; int xs0 = rsMax(0, startx + 0); @@ -147,13 +147,13 @@ static uchar2 OneBiCubic(const uchar2 *yp0, const uchar2 *yp1, const uchar2 *yp2 convert_float2(yp3[xs3]), xf); float2 p = cubicInterpolate(p0, p1, p2, p3, yf); - p = clamp(p, 0.f, 255.f); + p = clamp(p + 0.5f, 0.f, 255.f); return convert_uchar2(p); } static uchar OneBiCubic(const uchar *yp0, const uchar *yp1, const uchar *yp2, const uchar *yp3, float xf, float yf, int width) { - int startx = (int) floor(xf - 2); + int startx = (int) floor(xf - 1); xf = xf - floor(xf); int maxx = width - 1; int xs0 = rsMax(0, startx + 0); @@ -171,7 +171,7 @@ static uchar OneBiCubic(const uchar *yp0, const uchar *yp1, const uchar *yp2, co (float)yp3[xs2], (float)yp3[xs3], xf); float p = cubicInterpolate(p0, p1, p2, p3, yf); - p = clamp(p, 0.f, 255.f); + p = clamp(p + 0.5f, 0.f, 255.f); return (uchar)p; } @@ -189,8 +189,8 @@ void RsdCpuScriptIntrinsicResize::kernelU4(const RsForEachStubParamStruct *p, const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX; const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride; - float yf = p->y * cp->scaleY; - int starty = (int) floor(yf - 2); + float yf = (p->y + 0.5f) * cp->scaleY - 0.5f; + int starty = (int) floor(yf - 1); yf = yf - floor(yf); int maxy = srcHeight - 1; int ys0 = rsMax(0, starty + 0); @@ -208,7 +208,7 @@ void RsdCpuScriptIntrinsicResize::kernelU4(const RsForEachStubParamStruct *p, uint32_t x2 = xend; while(x1 < x2) { - float xf = x1 * cp->scaleX; + float xf = (x1 + 0.5f) * cp->scaleX - 0.5f; *out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth); out++; x1++; @@ -229,8 +229,8 @@ void RsdCpuScriptIntrinsicResize::kernelU2(const RsForEachStubParamStruct *p, const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX; const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride; - float yf = p->y * cp->scaleY; - int starty = (int) floor(yf - 2); + float yf = (p->y + 0.5f) * cp->scaleY - 0.5f; + int starty = (int) floor(yf - 1); yf = yf - floor(yf); int maxy = srcHeight - 1; int ys0 = rsMax(0, starty + 0); @@ -248,7 +248,7 @@ void RsdCpuScriptIntrinsicResize::kernelU2(const RsForEachStubParamStruct *p, uint32_t x2 = xend; while(x1 < x2) { - float xf = x1 * cp->scaleX; + float xf = (x1 + 0.5f) * cp->scaleX - 0.5f; *out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth); out++; x1++; @@ -269,8 +269,8 @@ void RsdCpuScriptIntrinsicResize::kernelU1(const RsForEachStubParamStruct *p, const int srcWidth = cp->mAlloc->mHal.drvState.lod[0].dimX; const size_t stride = cp->mAlloc->mHal.drvState.lod[0].stride; - float yf = p->y * cp->scaleY; - int starty = (int) floor(yf - 2); + float yf = (p->y + 0.5f) * cp->scaleY - 0.5f; + int starty = (int) floor(yf - 1); yf = yf - floor(yf); int maxy = srcHeight - 1; int ys0 = rsMax(0, starty + 0); @@ -288,7 +288,7 @@ void RsdCpuScriptIntrinsicResize::kernelU1(const RsForEachStubParamStruct *p, uint32_t x2 = xend; while(x1 < x2) { - float xf = x1 * cp->scaleX; + float xf = (x1 + 0.5f) * cp->scaleX - 0.5f; *out = OneBiCubic(yp0, yp1, yp2, yp3, xf, yf, srcWidth); out++; x1++; diff --git a/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp b/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp index c53ef313..e191e25d 100644 --- a/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp +++ b/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp @@ -161,8 +161,8 @@ void RsdCpuScriptIntrinsicYuvToRGB::kernel(const RsForEachStubParamStruct *p, out++; x1++; } -// reenable for ARM64 when intrinsic is fixed -#if defined(ARCH_ARM_USE_INTRINSICS) && !defined(ARCH_ARM64_USE_INTRINSICS) + +#if defined(ARCH_ARM_USE_INTRINSICS) if((x2 > x1) && gArchUseSIMD) { int32_t len = x2 - x1; if (cstep == 1) { diff --git a/cpu_ref/rsCpuIntrinsics_advsimd_Blur.S b/cpu_ref/rsCpuIntrinsics_advsimd_Blur.S index 929f76f7..fc1eefee 100644 --- a/cpu_ref/rsCpuIntrinsics_advsimd_Blur.S +++ b/cpu_ref/rsCpuIntrinsics_advsimd_Blur.S @@ -52,17 +52,17 @@ * x6 -- rup * x7 -- rdn * x12 -- switch index - * q0-q3 -- coefficient table + * v0-v3 -- coefficient table * x13 = -pitch * x15 = top-row in * x19 = bottom-row in * Output: * x1 += 16 - * q10,q11 -- 16 convolved columns + * v10,v11 -- 16 convolved columns * Modifies: * x10 = upper row pointer * x11 = lower row pointer - * q12-q15 = temporary sums + * v12-v15 = temporary sums */ .macro fetch, max_r=MAX_R, labelc=1, labelnc=2, reg=x12 /*{{{*/ .ifc \reg,x12 ; .set cc, 1 ; .else ; .set cc, 0 ; .endif @@ -146,15 +146,15 @@ nop * When the buffer gets too big the buffer at [x9] is used. * * Input: - * q4-q11 -- convoltion window + * v16-v31,v4-v11 -- convoltion window * x9 -- pointer to additional convolution window data * Output: * x9 -- updated buffer pointer (if used) * d31 -- result to be stored * Modifies: * x12 -- temp buffer pointer - * q12-q13 -- temporaries for load and vext operations. - * q14-q15 -- intermediate sums + * v12-v13 -- temporaries for load and vext operations. + * v14-v15 -- intermediate sums */ #define TUNED_LIST1 8, 16 .macro hconv1_8/*{{{*/ @@ -407,7 +407,7 @@ nop umlal2 v15.4s, v12.8h, v3.h[1] umlal v14.4s, v13.4h, v3.h[1] umlal2 v15.4s, v13.8h, v3.h[1] - 124: ext v12.16b, v3.16b, v4.16b, #7*2 + 124: ext v12.16b, v31.16b, v4.16b, #7*2 ext v13.16b, v9.16b, v10.16b, #7*2 umlal v14.4s, v12.4h, v3.h[0] umlal2 v15.4s, v12.8h, v3.h[0] @@ -1055,64 +1055,47 @@ PRIVATE(fetch_generic_asm) ret END(fetch_generic_asm) -/* Given values in q10 and q11, and an index in x11, sweep the (x11&15)th value +/* Given values in v10 and v11, and an index in x11, sweep the (x11&15)th value * across to fill the rest of the register pair. Used for filling the right * hand edge of the window when starting too close to the right hand edge of * the image. + * Also returns a dup-ed copy of the last element in v12 for the tail-fill + * case (this happens incidentally in common path, but must be done + * deliberately in the fast-out path). */ -PRIVATE(prefetch_clamp1) - sub x11, xzr, x11 - sub x15, x15, x1 - sub x19, x19, x1 - tbz x11, #3, 1f - mov v11.16b, v10.16b - sub x1, x1, #16 -1: mov v12.16b, v11.16b - movi v13.8b, #0xff - tbz x11, #2, 1f - ext v12.16b, v12.16b, v12.16b, #4*2 - sub x1, x1, #8 - shl v13.2d, v13.2d, #32 -1: tbz x11, #1, 1f - ext v12.16b, v12.16b, v12.16b, #6*2 - sub x1, x1, #4 - shl v13.2d, v13.2d, #16 -1: tbz x11, #0, 1f - ext v12.16b, v12.16b, v12.16b, #7*2 - sub x1, x1, #2 - shl v13.2d, v13.2d, #8 -1: dup v12.8h, v12.h[6] - sxtl v13.8h, v13.8b - bif v11.16b, v12.16b, v13.16b -1: tbz x11, #3, 1f - mov v10.16b, v11.16b - mov v11.16b, v12.16b -1: sub x11, xzr, x11 - add x15, x15, x1 - add x19, x19, x1 +PRIVATE(prefetch_clampright1) + ands x12, x11, #15 + beq 1f + sub x12, x12, #1 + sub sp, sp, #64 + st1 {v10.8h,v11.8h}, [sp] + add x12, sp, x12, LSL #1 + ld1r {v12.8h}, [x12] + st1 {v12.8h}, [x12], #16 + st1 {v12.8h}, [x12] + ld1 {v10.8h,v11.8h}, [sp] + add sp, sp, #64 + ret +1: dup v12.8h, v11.h[7] + ret +END(prefetch_clampright1) + +PRIVATE(prefetch_clampright4) + ands x12, x11, #15 + beq 1f + sub x12, x12, #4 + sub sp, sp, #64 + st1 {v10.8h,v11.8h}, [sp] + add x12, sp, x12, LSL #1 + ld1r {v12.2d}, [x12] + st1 {v12.8h}, [x12], #16 + st1 {v12.8h}, [x12] + ld1 {v10.8h,v11.8h}, [sp] + add sp, sp, #64 ret -END(prefetch_clamp1) - -PRIVATE(prefetch_clamp4) - sub x11, xzr, x11 - sub x15, x15, x1 - sub x19, x19, x1 - tbz x11, #3, 1f - sub x1, x1, #16 // what's this? - mov v11.16b, v10.16b 1: dup v12.2d, v11.d[1] - tbz x11, #2, 1f - dup v12.2d, v11.d[0] - sub x1, x1, #8 - dup v11.2d, v11.d[0] -1: tbz x11, #3, 1f - mov v10.16b, v11.16b - mov v11.16b, v12.16b -1: sub x11, xzr, x11 - add x15, x15, x1 - add x19, x19, x1 ret -END(prefetch_clamp4) +END(prefetch_clampright4) /* Helpers for prefetch, below. @@ -1147,10 +1130,10 @@ END(prefetch_clamp4) prefetch_out \qa, \qb, \store, v10.16b, v11.16b, v11.d[1] bl fetch_generic_asm b 2f -3: bl prefetch_clamp\step +3: bl prefetch_clampright\step prefetch_out \qa, \qb, \store, v10.16b, v11.16b, v11.d[1] 4: b 4f+4 - //v12 contains pad word from prefetch_clamp call + //v12 contains pad word from prefetch_clampright call prefetch_out \qa, \qb, \store, v12.16b, v12.16b, v12.d[1] .if \rem > 0 b 4f+4 @@ -1209,24 +1192,18 @@ END(prefetch_clamp4) .else dup v9.2d, v10.d[0] .endif - tst x10, #15 + ands x12, x10, #15 beq 2f - sub x12, xzr, x10 - tbz x10, #3, 1f - mov v11.16b, v10.16b - mov v10.16b, v9.16b -1: tbz x12, #2, 1f - ext v11.16b, v10.16b, v11.16b, #4*2 - ext v10.16b, v9.16b, v10.16b, #4*2 - .if \step == 1 - 1: tbz x12, #1, 1f - ext v11.16b, v10.16b, v11.16b, #2*2 - ext v10.16b, v9.16b, v10.16b, #2*2 - 1: tbz x12, #0, 1f - ext v11.16b, v10.16b, v11.16b, #1*2 - ext v10.16b, v9.16b, v10.16b, #1*2 - .endif -1: sub x1, x1, x10 + sub sp, sp, #32 + st1 {v10.8h,v11.8h}, [sp] + sub x12, sp, x12, LSL #1 + sub sp, sp, #16 + st1 {v9.8h}, [sp] + sub sp, sp, #16 + st1 {v9.8h}, [sp] + ld1 {v10.8h,v11.8h}, [x12] + add sp, sp, #64 + sub x1, x1, x10 sub x15, x15, x10 sub x19, x19, x10 bic x10, x10, #15 @@ -1363,13 +1340,13 @@ END(prefetch_clamp4) b 3b 4: tbz x3, #2, 1f st1 {v15.s}[0], [x0], #4 - ext v15.16b, v15.16b, v15.16b, #4*2 + ext v15.8b, v15.8b, v15.8b, #4 1: tbz x3, #1, 1f st1 {v15.h}[0], [x0], #2 - ext v15.16b, v15.16b, v15.16b, #2*2 + ext v15.8b, v15.8b, v15.8b, #2 1: tbz x3, #0, 5f st1 {v15.b}[0], [x0], #1 - ext v15.16b, v15.16b, v15.16b, #1*2 + ext v15.8b, v15.8b, v15.8b, #1 5: nop .endm @@ -1438,7 +1415,6 @@ ENTRY(rsdIntrinsicBlurU1_K) ldr x12, [sp, #88] // tab - add x0, x0, x8 add x1, x1, x8 cmp x6, x5 @@ -1448,7 +1424,7 @@ ENTRY(rsdIntrinsicBlurU1_K) cmp x8, x5 csel x8, x5, x8, hs cmp x9, x5 - csel x9, x5, x8, hs + csel x9, x5, x9, hs add x4, x8, x9 add x4, x4, x3 @@ -1504,7 +1480,6 @@ ENTRY(rsdIntrinsicBlurU4_K) ldr x12, [sp, #88] - add x0, x0, x8, LSL #2 add x1, x1, x8, LSL #2 cmp x6, x5 diff --git a/cpu_ref/rsCpuIntrinsics_advsimd_YuvToRGB.S b/cpu_ref/rsCpuIntrinsics_advsimd_YuvToRGB.S index 632ef7a4..bb4b7ae3 100644 --- a/cpu_ref/rsCpuIntrinsics_advsimd_YuvToRGB.S +++ b/cpu_ref/rsCpuIntrinsics_advsimd_YuvToRGB.S @@ -21,60 +21,127 @@ * register. This macro will be called from within several different wrapper * variants for different data layouts. Y data starts with the even and odd * bytes split into the low parts of v8 and v9 respectively. U and V are in - * v16 and v17. Working constants are pre-loaded into v13-v15, and v3 is - * pre-loaded with a constant 0xff alpha channel. + * v10 and v11. Working constants are pre-loaded into v24-v31, and v3 and v7 + * are pre-loaded with a constant 0xff alpha channel. * * The complicated arithmetic is the result of refactoring the original * equations to avoid 16-bit overflow without losing any precision. */ -.macro yuvkern - movi v7.8b, #149 - - umull v1.8h, v8.8b, v7.8b // g0 = y0 * 149 - umull v5.8h, v9.8b, v7.8b // g1 = y1 * 149 - - movi v7.8b, #50 - movi v10.8b, #104 - umull v8.8h, v16.8b, v7.8b // g2 = u * 50 + v * 104 - umlal v8.8h, v17.8b, v10.8b - - ushr v7.8b, v17.8b, #1 - uaddw v0.8h, v1.8h, v7.8b // r0 = y0 * 149 + (v >> 1) - uaddw v4.8h, v5.8h, v7.8b // r1 = y1 * 149 + (v >> 1) - - ushll v7.8h, v16.8b, #2 - add v2.8h, v1.8h, v7.8h // b0 = y0 * 149 + (u << 2) - add v6.8h, v5.8h, v7.8h // b1 = y1 * 149 + (u << 2) - - movi v7.16b, #204 - movi v10.8b, #254 - umull v11.8h, v17.8b, v7.8b // r2 = v * 204 - umull v12.8h, v16.8b, v10.8b // b2 = u * 254 - - uhadd v0.8h, v0.8h, v11.8h // r0 = (r0 + r2) >> 1 - uhadd v4.8h, v4.8h, v11.8h // r1 = (r1 + r2) >> 1 - uqadd v1.8h, v1.8h, v14.8h // g0 = satu16(g0 + (-16 * 149 + 128 * 50 + 128 * 104) >> 0) - uqadd v5.8h, v5.8h, v14.8h // g1 = satu16(g1 + (-16 * 149 + 128 * 50 + 128 * 104) >> 0) - uhadd v2.8h, v2.8h, v12.8h // b0 = (b0 + b2) >> 1 - uhadd v6.8h, v6.8h, v12.8h // b1 = (b1 + b2) >> 1 - - uqsub v0.8h, v0.8h, v13.8h // r0 = satu16(r0 - (16 * 149 + (128 >> 1) + 128 * 204) >> 1) - uqsub v4.8h, v4.8h, v13.8h // r1 = satu16(r1 - (16 * 149 + (128 >> 1) + 128 * 204) >> 1) - uqsub v1.8h, v1.8h, v8.8h // g0 = satu16(g0 - g2) - uqsub v5.8h, v5.8h, v8.8h // g1 = satu16(g1 - g2) - uqsub v2.8h, v2.8h, v15.8h // b0 = satu16(b0 - (16 * 149 + (128 << 2) + 128 * 254) >> 1) - uqsub v6.8h, v6.8h, v15.8h // b1 = satu16(b1 - (16 * 149 + (128 << 2) + 128 * 254) >> 1) - - uqrshrn v0.8b, v0.8h, #6 - uqrshrn v4.8b, v4.8h, #6 - uqrshrn v1.8b, v1.8h, #7 - uqrshrn v5.8b, v5.8h, #7 - uqrshrn v2.8b, v2.8h, #6 - uqrshrn v6.8b, v6.8h, #6 - - zip1 v0.16b, v0.16b, v4.16b - zip1 v1.16b, v1.16b, v5.16b - zip1 v2.16b, v2.16b, v6.16b +.macro yuvkern, regu=v10, regv=v11 + /* v0 out R_lo / even R_lo accumulator + * v1 out G_lo / even G_lo accumulator + * v2 out B_lo / even B_lo accumulator + * v3 out A_lo / const 0xff*ff + * v4 out R_hi / even R_hi accumulator + * v5 out G_hi / even G_hi accumulator + * v6 out B_hi / even B_hi accumulator + * v7 out A_hi / const 0xff*ff + * v8 even Y / G_lo luma tmp + * v9 odd Y / G_lo luma tmp + * \regu in U + * \regv in V + * v12 R_lo luma tmp + * v13 B_lo luma tmp + * v14 R_hi luma tmp + * v15 B_hi luma tmp + * v16 odd R_lo accumulator + * v17 odd G_lo accumulator + * v18 odd B_lo accumulator + * v19 multiplier extra bits low + * v20 odd R_hi accumulator + * v21 odd G_hi accumulator + * v22 odd B_hi accumulator + * v23 multiplier extra bits high + * v24 constant 149 + * v25 constant 50 + * v26 constant 104 + * v27 constant 204 + * v28 constant 254 + * v29 constant ((16 * 149 + (128 >> 1) + 128 * 204) >> 1) + * v30 constant ((-16 * 149 + 128 * 50 + 128 * 104) >> 0) + * v31 constant ((16 * 149 + (128 << 2) + 128 * 254) >> 1) + */ + + umull v1.8h, v8.8b, v24.8b // g0 = y0 * 149 + umull v17.8h, v9.8b, v24.8b // g1 = y1 * 149 + umull2 v5.8h, v8.16b, v24.16b // g0_hi = y0_hi * 149 + umull2 v21.8h, v9.16b, v24.16b // g1_hi = y1_hi * 149 + + umull v8.8h, \regu\().8b, v25.8b // g2 = u * 50 + v * 104 + umlal v8.8h, \regv\().8b, v26.8b + umull2 v9.8h, \regu\().16b, v25.16b // g2_hi = u_hi * 50 + v_hi * 104 + umlal2 v9.8h, \regv\().16b, v26.16b + + ushr v19.16b, \regv\().16b, #1 + uaddw v0.8h, v1.8h, v19.8b // r0 = g0 + (v >> 1) + uaddw v16.8h, v17.8h, v19.8b // r1 = g1 + (v >> 1) + + uaddw2 v4.8h, v5.8h, v19.16b // r0_hi = g0_hi + (v_hi >> 1) + uaddw2 v20.8h, v21.8h, v19.16b // r1_hi = g1_hi + (v_hi >> 1) + + ushll v19.8h, \regu\().8b, #2 + ushll2 v23.8h, \regu\().16b, #2 + add v2.8h, v1.8h, v19.8h // b0 = g0 + (u << 2) + add v18.8h, v17.8h, v19.8h // b1 = g1 + (u << 2) + + add v6.8h, v5.8h, v23.8h // b0_hi = g0_hi + (u_hi << 2) + add v22.8h, v21.8h, v23.8h // b1_hi = g1_hi + (u_hi << 2) + + umull v12.8h, \regv\().8b, v27.8b // r2 = v * 204 + umull v13.8h, \regu\().8b, v28.8b // b2 = u * 254 + + umull2 v14.8h, \regv\().16b, v27.16b // r2_hi = v_hi * 204 + umull2 v15.8h, \regu\().16b, v28.16b // b2_hi = u_hi * 254 + + uhadd v0.8h, v0.8h, v12.8h // r0 = (r0 + r2) >> 1 + uhadd v16.8h, v16.8h, v12.8h // r1 = (r1 + r2) >> 1 + uqadd v1.8h, v1.8h, v30.8h // g0 = satu16(g0 + (-16 * 149 + 128 * 50 + 128 * 104) >> 0) + uqadd v17.8h, v17.8h, v30.8h // g1 = satu16(g1 + (-16 * 149 + 128 * 50 + 128 * 104) >> 0) + uhadd v2.8h, v2.8h, v13.8h // b0 = (b0 + b2) >> 1 + uhadd v18.8h, v18.8h, v13.8h // b1 = (b1 + b2) >> 1 + + uhadd v4.8h, v4.8h, v14.8h // r0_hi = (r0_hi + r2_hi) >> 1 + uhadd v20.8h, v20.8h, v14.8h // r1_hi = (r1_hi + r2_hi) >> 1 + uqadd v5.8h, v5.8h, v30.8h // g0_hi = satu16(g0_hi + (-16 * 149 + 128 * 50 + 128 * 104) >> 0) + uqadd v21.8h, v21.8h, v30.8h // g1_hi = satu16(g1_hi + (-16 * 149 + 128 * 50 + 128 * 104) >> 0) + uhadd v6.8h, v6.8h, v15.8h // b0_hi = (b0_hi + b2_hi) >> 1 + uhadd v22.8h, v22.8h, v15.8h // b1_hi = (b1_hi + b2_hi) >> 1 + + uqsub v0.8h, v0.8h, v29.8h // r0 = satu16(r0 - (16 * 149 + (128 >> 1) + 128 * 204) >> 1) + uqsub v16.8h, v16.8h, v29.8h // r1 = satu16(r1 - (16 * 149 + (128 >> 1) + 128 * 204) >> 1) + uqsub v1.8h, v1.8h, v8.8h // g0 = satu16(g0 - g2) + uqsub v17.8h, v17.8h, v8.8h // g1 = satu16(g1 - g2) + uqsub v2.8h, v2.8h, v31.8h // b0 = satu16(b0 - (16 * 149 + (128 << 2) + 128 * 254) >> 1) + uqsub v18.8h, v18.8h, v31.8h // b1 = satu16(b1 - (16 * 149 + (128 << 2) + 128 * 254) >> 1) + + uqsub v4.8h, v4.8h, v29.8h // r0_hi = satu16(r0_hi - (16 * 149 + (128 >> 1) + 128 * 204) >> 1) + uqsub v20.8h, v20.8h, v29.8h // r1_hi = satu16(r1_hi - (16 * 149 + (128 >> 1) + 128 * 204) >> 1) + uqsub v5.8h, v5.8h, v9.8h // g0_hi = satu16(g0_hi - g2_hi) + uqsub v21.8h, v21.8h, v9.8h // g1_hi = satu16(g1_hi - g2_hi) + uqsub v6.8h, v6.8h, v31.8h // b0_hi = satu16(b0_hi - (16 * 149 + (128 << 2) + 128 * 254) >> 1) + uqsub v22.8h, v22.8h, v31.8h // b1_hi = satu16(b1_hi - (16 * 149 + (128 << 2) + 128 * 254) >> 1) + + uqrshrn v0.8b, v0.8h, #6 + uqrshrn v16.8b, v16.8h, #6 + uqrshrn v1.8b, v1.8h, #7 + uqrshrn v17.8b, v17.8h, #7 + uqrshrn v2.8b, v2.8h, #6 + uqrshrn v18.8b, v18.8h, #6 + + uqrshrn v4.8b, v4.8h, #6 + uqrshrn v20.8b, v20.8h, #6 + uqrshrn v5.8b, v5.8h, #7 + uqrshrn v21.8b, v21.8h, #7 + uqrshrn v6.8b, v6.8h, #6 + uqrshrn v22.8b, v22.8h, #6 + + zip1 v0.16b, v0.16b, v16.16b + zip1 v1.16b, v1.16b, v17.16b + zip1 v2.16b, v2.16b, v18.16b + + zip1 v4.16b, v4.16b, v20.16b + zip1 v5.16b, v5.16b, v21.16b + zip1 v6.16b, v6.16b, v22.16b .endm /* Define the wrapper code which will load and store the data, iterate the @@ -83,50 +150,51 @@ * being handled. */ .macro wrap_line kernel, interleaved=0, swapuv=0 - + movi v24.16b, #149 + movi v25.16b, #50 + movi v26.16b, #104 + movi v27.16b, #204 + movi v28.16b, #254 mov w5, #((16 * 149 + (128 >> 1) + 128 * 204) >> 1) - dup v13.8h, w5 + dup v29.8h, w5 mov w5, #((-16 * 149 + 128 * 50 + 128 * 104) >> 0) - dup v14.8h, w5 + dup v30.8h, w5 mov w5, #((16 * 149 + (128 << 2) + 128 * 254) >> 1) - dup v15.8h, w5 + dup v31.8h, w5 movi v3.16b, #0xff + movi v7.16b, #0xff - subs x2, x2, #16 + subs x2, x2, #32 bhs 1f b 2f .align 4 -1: ld2 {v8.8b,v9.8b}, [x1], #16 -// prfm PLDL1STRM, [x1, #256] +1: ld2 {v8.16b,v9.16b}, [x1], #32 .if \interleaved - .if \swapuv - ld2 {v17.8b,v18.8b}, [x3], #16 - mov v16.8b, v18.8b - .else - ld2 {v16.8b,v17.8b}, [x3], #16 - .endif -// prfm PLD1STRM, [x3, #256] + ld2 {v10.16b,v11.16b}, [x3], #32 .else - ld1 {v16.8b}, [x3], #8 - ld1 {v17.8b}, [x4], #8 -// prfm PLD1STRM, [x3, #128] -// prfm PLD1STRM, [x4, #128] + ld1 {v10.16b}, [x3], #16 + ld1 {v11.16b}, [x4], #16 .endif + .if \swapuv + \kernel regu=v11, regv=v10 + .else \kernel + .endif - subs x2, x2, #16 + subs x2, x2, #32 - st4 {v0.16b,v1.16b,v2.16b,v3.16b}, [x0], #64 + st4 {v0.16b - v3.16b}, [x0], #64 + st4 {v4.16b - v7.16b}, [x0], #64 bhs 1b -2: adds x2, x2, #16 +2: adds x2, x2, #32 beq 2f - /* To handle the tail portion of the data (something less than 16 + /* To handle the tail portion of the data (something less than 32 * bytes) load small power-of-two chunks into working registers. It * doesn't matter where they end up in the register; the same process * will store them back out using the same positions and the @@ -135,40 +203,48 @@ */ movi v8.8b, #0 movi v9.8b, #0 - movi v16.8b, #0 - movi v17.8b, #0 + movi v10.8b, #0 + movi v11.8b, #0 - tbz x2, #3, 1f - ld1 {v9.8b}, [x1], #8 + tbz x2, #4, 1f + ld1 {v9.16b}, [x1], #16 + .if \interleaved + ld1 {v11.16b}, [x3], #16 + .else + ld1 {v10.d}[1], [x3], #8 + ld1 {v11.d}[1], [x4], #8 + .endif +1: tbz x2, #3, 1f + ld1 {v8.d}[1], [x1], #8 .if \interleaved - ld1 {v17.8b}, [x3], #8 + ld1 {v10.d}[1], [x3], #8 .else - ld1 {v16.s}[1], [x3], #4 - ld1 {v17.s}[1], [x4], #4 + ld1 {v10.s}[1], [x3], #4 + ld1 {v11.s}[1], [x4], #4 .endif 1: tbz x2, #2, 1f ld1 {v8.s}[1], [x1], #4 .if \interleaved - ld1 {v16.s}[1], [x3], #4 + ld1 {v10.s}[1], [x3], #4 .else - ld1 {v16.h}[1], [x3], #2 - ld1 {v17.h}[1], [x4], #2 + ld1 {v10.h}[1], [x3], #2 + ld1 {v11.h}[1], [x4], #2 .endif 1: tbz x2, #1, 1f ld1 {v8.h}[1], [x1], #2 .if \interleaved - ld1 {v16.h}[1], [x3], #2 + ld1 {v10.h}[1], [x3], #2 .else - ld1 {v16.b}[1], [x3], #1 - ld1 {v17.b}[1], [x4], #1 + ld1 {v10.b}[1], [x3], #1 + ld1 {v11.b}[1], [x4], #1 .endif 1: tbz x2, #0, 1f ld1 {v8.b}[1], [x1], #1 .if \interleaved - ld1 {v16.h}[0], [x3], #2 + ld1 {v10.h}[0], [x3], #2 .else - ld1 {v16.b}[0], [x3], #1 - ld1 {v17.b}[0], [x4], #1 + ld1 {v10.b}[0], [x3], #1 + ld1 {v11.b}[0], [x4], #1 .endif /* One small impediment in the process above is that some of the load @@ -176,29 +252,38 @@ * same time as loading only part of a register. So the data is loaded * linearly and unpacked manually at this point if necessary. */ -1: uzp1 v8.16b, v8.16b, v9.16b +1: mov v12.16b, v8.16b + uzp1 v8.16b, v12.16b, v9.16b + uzp2 v9.16b, v12.16b, v9.16b .if \interleaved - .if \swapuv - uzp1 v16.16b, v17.16b, v16.16b - .else - uzp1 v16.16b, v16.16b, v17.16b - .endif + mov v12.16b, v10.16b + uzp1 v10.16b, v12.16b, v11.16b + uzp2 v11.16b, v12.16b, v11.16b .endif + .if \swapuv + \kernel regu=v11, regv=v10 + .else \kernel + .endif /* As above but with the output; structured stores for partial vectors * aren't available, so the data is re-packed first and stored linearly. */ - zip1 v4.16b, v0.16b, v2.16b - zip2 v6.16b, v0.16b, v2.16b - zip1 v5.16b, v1.16b, v3.16b - zip2 v7.16b, v1.16b, v3.16b - zip1 v0.16b, v4.16b, v5.16b - zip2 v1.16b, v4.16b, v5.16b - zip1 v2.16b, v6.16b, v7.16b - zip2 v3.16b, v6.16b, v7.16b - + zip1 v16.16b, v0.16b, v2.16b + zip2 v18.16b, v0.16b, v2.16b + zip1 v17.16b, v1.16b, v3.16b + zip2 v19.16b, v1.16b, v3.16b + zip1 v0.16b, v16.16b, v17.16b + zip2 v1.16b, v16.16b, v17.16b + zip1 v2.16b, v18.16b, v19.16b + zip2 v3.16b, v18.16b, v19.16b + + /* Luckily v4-v7 don't need to be unzipped because the complete set of + * four and can be stored using st4. */ + + tbz x2, #4, 1f + st4 {v4.16b - v7.16b}, [x0], #64 1: tbz x2, #3, 1f st1 {v2.16b,v3.16b}, [x0], #32 1: tbz x2, #2, 1f @@ -225,7 +310,7 @@ ENTRY(rsdIntrinsicYuv2_K) add x1, x1, x4 add x4, x3, x6 add x3, x2, x6 - sub x2, x5, x6, LSL #2 + sub x2, x5, x6, LSL #1 sub x6, sp, #32 sub sp, sp, #64 diff --git a/cpu_ref/rsCpuIntrinsics_neon_Blur.S b/cpu_ref/rsCpuIntrinsics_neon_Blur.S index 8fc47f5b..a7ae795c 100644 --- a/cpu_ref/rsCpuIntrinsics_neon_Blur.S +++ b/cpu_ref/rsCpuIntrinsics_neon_Blur.S @@ -15,6 +15,7 @@ */ #define ENTRY(f) .text; .align 4; .globl f; .type f,#function; f: .fnstart +#define PRIVATE(f) .text; .align 4; .type f,#function; f: .fnstart #define END(f) .fnend; .size f, .-f; .eabi_attribute 25,1 @Tag_ABI_align8_preserved @@ -1049,7 +1050,7 @@ /* Dedicated function wrapper for the fetch macro, for the cases where * performance isn't that important, to keep code size down. */ -ENTRY(fetch_generic_asm) +PRIVATE(fetch_generic_asm) push {r10,r11} fetch pop {r10,r11} @@ -1060,61 +1061,46 @@ END(fetch_generic_asm) * across to fill the rest of the register pair. Used for filling the right * hand edge of the window when starting too close to the right hand edge of * the image. + * Also returns a dup-ed copy of the last element in q12 for the tail-fill + * case (this happens incidentally in common path, but must be done + * deliberately in the fast-out path). */ -ENTRY(prefetch_clamp1) - rsb r11, r11, #0 - tst r11, #8 +PRIVATE(prefetch_clampright1) + ands r12, r11, #15 beq 1f - vmov.u16 q11, q10 - sub r1, r1, #16 -1: vmov.u16 q12, q11 - vmov.i8 d26, #0xff - tst r11, #4 - beq 1f - vext.u16 q12, q12, q12, #4 - sub r1, r1, #8 - vshl.u64 d26, d26, #32 -1: tst r11, #2 - beq 1f - vext.u16 q12, q12, q12, #6 - sub r1, r1, #4 - vshl.u64 d26, d26, #16 -1: tst r11, #1 - beq 1f - vext.u16 q12, q12, q12, #7 - sub r1, r1, #2 - vshl.u64 d26, d26, #8 -1: vdup.u16 q12, d25[2] - vmovl.s8 q13, d26 - vbif q11, q12, q13 -1: tst r11, #8 - beq 1f - vmov q10, q11 - vmov q11, q12 -1: rsb r11, r11, #0 + sub r12, r12, #1 + sub sp, sp, #64 + vst1.u16 {q10,q11}, [sp] + add r12, sp, r12, LSL #1 + vld1.u16 {d24[]}, [r12] + vld1.u16 {d25[]}, [r12] + vst1.u16 {q12}, [r12]! + vst1.u16 {q12}, [r12] + vld1.u16 {q10,q11}, [sp] + add sp, sp, #64 + bx lr +1: vdup.u16 q12, d23[3] bx lr -END(prefetch_clamp1) +END(prefetch_clampright1) -ENTRY(prefetch_clamp4) - rsb r11, r11, #0 - tst r11, #8 - beq 1f - sub r1, r1, #16 - vmov.u16 q11, q10 -1: vmov d24, d23 - tst r11, #4 - beq 1f - vmov d24, d22 - sub r1, r1, #8 - vmov d23, d22 -1: vmov d25, d24 - tst r11, #8 +PRIVATE(prefetch_clampright4) + ands r12, r11, #15 beq 1f - vmov q10, q11 - vmov q11, q12 -1: rsb r11, r11, #0 + sub r12, r12, #4 + sub sp, sp, #64 + vst1.u16 {q10,q11}, [sp] + add r12, sp, r12, LSL #1 + vld1.u64 {d24}, [r12] + vld1.u64 {d25}, [r12] + vst1.u16 {q12}, [r12]! + vst1.u16 {q12}, [r12] + vld1.u16 {q10,q11}, [sp] + add sp, sp, #64 + bx lr +1: vmov.u16 d24, d23 + vmov.u16 d25, d23 bx lr -END(prefetch_clamp4) +END(prefetch_clampright4) /* Helpers for prefetch, below. @@ -1147,10 +1133,10 @@ END(prefetch_clamp4) prefetch_out \qa, \qb, \store, q10, q11, d23 bl fetch_generic_asm b 2f -3: bl prefetch_clamp\step +3: bl prefetch_clampright\step prefetch_out \qa, \qb, \store, q10, q11, d23 4: b 4f+4 - @q12 contains pad word from prefetch_clam call + @q12 contains pad word from prefetch_clampright call prefetch_out \qa, \qb, \store, q12, q12, d25 .if \rem > 0 b 4f+4 @@ -1205,28 +1191,18 @@ END(prefetch_clamp4) vmov.u16 d18, d20 vmov.u16 d19, d20 .endif - tst r10, #15 + ands r12, r10, #15 beq 2f - rsb r12, r10, #0 - tst r10, #8 - beq 1f - vmov.u16 q11, q10 - vmov.u16 q10, q9 -1: tst r12, #4 - beq 1f - vext.u16 q11, q10, q11, #4 - vext.u16 q10, q9, q10, #4 - .if \step == 1 - 1: tst r12, #2 - beq 1f - vext.u16 q11, q10, q11, #2 - vext.u16 q10, q9, q10, #2 - 1: tst r12, #1 - beq 1f - vext.u16 q11, q10, q11, #1 - vext.u16 q10, q9, q10, #1 - .endif -1: sub r1, r1, r10 + sub sp, sp, #32 + vst1.u16 {q10,q11}, [sp] + sub r12, sp, r12, LSL #1 + sub sp, sp, #16 + vst1.u16 {q9}, [sp] + sub sp, sp, #16 + vst1.u16 {q9}, [sp] + vld1.u16 {q10,q11}, [r12] + add sp, sp, #64 + sub r1, r1, r10 bic r10, r10, #15 add r1, r1, r10 2: @@ -1383,7 +1359,7 @@ END(prefetch_clamp4) .endm .irep r, TUNED_LIST1, 25 -ENTRY(convolve1_\r) +PRIVATE(convolve1_\r) push {r12,lr} sub r1, r1, r8 @@ -1397,7 +1373,7 @@ END(convolve1_\r) .endr .irep r, TUNED_LIST4, 25 -ENTRY(convolve4_\r) +PRIVATE(convolve4_\r) sub r12, sp, #0x200 bic r9, r12, #0x3fc mov sp, r9 @@ -1447,8 +1423,7 @@ ENTRY(rsdIntrinsicBlurU1_K) ldr r12, [sp,#124] - add r0, r0, r8 @, LSL #2 /* for blur4 option */ - add r1, r1, r8 @, LSL #2 /* for blur4 option */ + add r1, r1, r8 cmp r6, r5 movhi r6, r5 @@ -1503,7 +1478,6 @@ ENTRY(rsdIntrinsicBlurU4_K) ldr r12, [sp,#124] - add r0, r0, r8, LSL #2 add r1, r1, r8, LSL #2 cmp r6, r5 diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp index a11fda19..e8b3fb6d 100644 --- a/cpu_ref/rsCpuScript.cpp +++ b/cpu_ref/rsCpuScript.cpp @@ -230,6 +230,11 @@ static void setCompileArguments(std::vector<const char*>* args, const android::S args->push_back("-mtriple"); args->push_back(DEFAULT_TARGET_TRIPLE_STRING); + // Enable workaround for A53 codegen by default. +#if defined(__aarch64__) && !defined(DISABLE_A53_WORKAROUND) + args->push_back("-aarch64-fix-cortex-a53-835769"); +#endif + // Execute the bcc compiler. if (useRSDebugContext) { args->push_back("-rs-debug-ctx"); diff --git a/driver/runtime/arch/asimd.ll b/driver/runtime/arch/asimd.ll index e1a54b48..efc53c89 100644 --- a/driver/runtime/arch/asimd.ll +++ b/driver/runtime/arch/asimd.ll @@ -1116,8 +1116,8 @@ define <4 x i8> @_Z17rsPackColorTo8888Dv4_f(<4 x float> %color) nounwind readnon } ; uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color) -define <4 x i8> @_Z17rsPackColorTo8888Dv3_f(<3 x float> %color) nounwind readnone { - %1 = shufflevector <3 x float> %color, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> +define <4 x i8> @_Z17rsPackColorTo8888Dv3_f(<4 x i32> %color) nounwind readnone { + %1 = bitcast <4 x i32> %color to <4 x float> %2 = insertelement <4 x float> %1, float 1.0, i32 3 %3 = tail call <4 x i8> @_Z17rsPackColorTo8888Dv4_f(<4 x float> %2) nounwind readnone ret <4 x i8> %3 diff --git a/driver/runtime/ll32/allocation.ll b/driver/runtime/ll32/allocation.ll index d0b3932b..21d7cac5 100644 --- a/driver/runtime/ll32/allocation.ll +++ b/driver/runtime/ll32/allocation.ll @@ -650,17 +650,20 @@ define void @rsGetElementAtImpl_double4(<4 x double>* noalias nocapture sret %ag } -define <4 x i64> @__rsAllocationVLoadXImpl_long4([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_long4(<4 x i64>* noalias nocapture sret %agg.result, [1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <4 x i64>* %3 = load <4 x i64>* %2, align 8 - ret <4 x i64> %3 + store <4 x i64> %3, <4 x i64>* %agg.result, align 32, !tbaa !52 + ret void } -define <3 x i64> @__rsAllocationVLoadXImpl_long3([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_long3(<3 x i64>* noalias nocapture sret %agg.result, [1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 - %2 = bitcast i8* %1 to <3 x i64>* - %3 = load <3 x i64>* %2, align 8 - ret <3 x i64> %3 + %2 = bitcast i8* %1 to <4 x i64>* + %3 = load <4 x i64>* %2, align 8 + %4 = bitcast <3 x i64>* %agg.result to <4 x i64>* + store <4 x i64> %3, <4 x i64>* %4, align 32, !tbaa !47 + ret void } define <2 x i64> @__rsAllocationVLoadXImpl_long2([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 @@ -669,17 +672,20 @@ define <2 x i64> @__rsAllocationVLoadXImpl_long2([1 x i32] %a.coerce, i32 %x, i3 ret <2 x i64> %3 } -define <4 x i64> @__rsAllocationVLoadXImpl_ulong4([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_ulong4(<4 x i64>* noalias nocapture sret %agg.result, [1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <4 x i64>* %3 = load <4 x i64>* %2, align 8 - ret <4 x i64> %3 + store <4 x i64> %3, <4 x i64>* %agg.result, align 32, !tbaa !48 + ret void } -define <3 x i64> @__rsAllocationVLoadXImpl_ulong3([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_ulong3(<3 x i64>* noalias nocapture sret %agg.result, [1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 - %2 = bitcast i8* %1 to <3 x i64>* - %3 = load <3 x i64>* %2, align 8 - ret <3 x i64> %3 + %2 = bitcast i8* %1 to <4 x i64>* + %3 = load <4 x i64>* %2, align 8 + %4 = bitcast <3 x i64>* %agg.result to <4 x i64>* + store <4 x i64> %3, <4 x i64>* %4, align 32, !tbaa !51 + ret void } define <2 x i64> @__rsAllocationVLoadXImpl_ulong2([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 @@ -821,17 +827,20 @@ define <2 x float> @__rsAllocationVLoadXImpl_float2([1 x i32] %a.coerce, i32 %x, ret <2 x float> %3 } -define <4 x double> @__rsAllocationVLoadXImpl_double4([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_double4(<4 x double>* noalias nocapture sret %agg.result, [1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <4 x double>* %3 = load <4 x double>* %2, align 8 - ret <4 x double> %3 + store <4 x double> %3, <4 x double>* %agg.result, align 32, !tbaa !60 + ret void } -define <3 x double> @__rsAllocationVLoadXImpl_double3([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_double3(<3 x double>* noalias nocapture sret %agg.result, [1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 - %2 = bitcast i8* %1 to <3 x double>* - %3 = load <3 x double>* %2, align 8 - ret <3 x double> %3 + %2 = bitcast i8* %1 to <4 x double>* + %3 = load <4 x double>* %2, align 8 + %4 = bitcast <3 x double>* %agg.result to <4 x double>* + store <4 x double> %3, <4 x double>* %4, align 32, !tbaa !59 + ret void } define <2 x double> @__rsAllocationVLoadXImpl_double2([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #0 { %1 = tail call i8* @rsOffsetNs([1 x i32] %a.coerce, i32 %x, i32 %y, i32 %z) #2 diff --git a/driver/runtime/ll64/allocation.ll b/driver/runtime/ll64/allocation.ll index d026ce82..c667b4b6 100644 --- a/driver/runtime/ll64/allocation.ll +++ b/driver/runtime/ll64/allocation.ll @@ -665,14 +665,14 @@ define void @rsGetElementAtImpl_double4(<4 x double>* noalias nocapture sret %ag } -define void @__rsAllocationVLoadXImpl_long4(<4 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_long4(<4 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs(%struct.rs_allocation* %a, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <4 x i64>* %3 = load <4 x i64>* %2, align 8 store <4 x i64> %3, <4 x i64>* %agg.result ret void } -define void @__rsAllocationVLoadXImpl_long3(<3 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_long3(<3 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs(%struct.rs_allocation* %a, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <3 x i64>* %3 = load <3 x i64>* %2, align 8 @@ -686,14 +686,14 @@ define <2 x i64> @__rsAllocationVLoadXImpl_long2(%struct.rs_allocation* nocaptur ret <2 x i64> %3 } -define void @__rsAllocationVLoadXImpl_ulong4(<4 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_ulong4(<4 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs(%struct.rs_allocation* %a, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <4 x i64>* %3 = load <4 x i64>* %2, align 8 store <4 x i64> %3, <4 x i64>* %agg.result ret void } -define void @__rsAllocationVLoadXImpl_ulong3(<3 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_ulong3(<3 x i64>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs(%struct.rs_allocation* %a, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <3 x i64>* %3 = load <3 x i64>* %2, align 8 @@ -840,14 +840,14 @@ define <2 x float> @__rsAllocationVLoadXImpl_float2(%struct.rs_allocation* nocap ret <2 x float> %3 } -define void @__rsAllocationVLoadXImpl_double4(<4 x double>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_double4(<4 x double>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs(%struct.rs_allocation* %a, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <4 x double>* %3 = load <4 x double>* %2, align 8 store <4 x double> %3, <4 x double>* %agg.result ret void } -define void @__rsAllocationVLoadXImpl_double3(<3 x double>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #0 { +define void @__rsAllocationVLoadXImpl_double3(<3 x double>* noalias nocapture sret %agg.result, %struct.rs_allocation* nocapture readonly %a, i32 %x, i32 %y, i32 %z) #1 { %1 = tail call i8* @rsOffsetNs(%struct.rs_allocation* %a, i32 %x, i32 %y, i32 %z) #2 %2 = bitcast i8* %1 to <3 x double>* %3 = load <3 x double>* %2, align 8 diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java index 7cf7caf2..e34666a0 100644 --- a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java +++ b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -103,8 +103,8 @@ public class ImageProcessingActivity extends Activity HISTOGRAM ("Histogram"), MANDELBROT_DOUBLE ("Mandelbrot fp64"), RESIZE_BICUBIC_SCRIPT ("Resize BiCubic Script"), - RESIZE_BICUBIC_INTRINSIC ("Resize BiCubic Intrinsic"); - + RESIZE_BICUBIC_INTRINSIC ("Resize BiCubic Intrinsic"), + MIRROR ("Mirror Image"); private final String name; @@ -374,6 +374,9 @@ public class ImageProcessingActivity extends Activity case RESIZE_BICUBIC_INTRINSIC: mTest = new Resize(true); break; + case MIRROR: + mTest = new Mirror(); + break; } mTest.createBaseTest(this); diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java index 1a4793cf..7c8ce631 100644 --- a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java +++ b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java @@ -404,4 +404,10 @@ public class ImageProcessingTest extends ActivityInstrumentationTestCase2<ImageP TestAction ta = new TestAction(TestName.MANDELBROT_DOUBLE); runTest(ta, TestName.MANDELBROT_DOUBLE.name()); } + // Test case 42: Mirror + @LargeTest + public void testMirror() { + TestAction ta = new TestAction(TestName.MIRROR); + runTest(ta, TestName.MIRROR.name()); + } } diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/Mirror.java b/java/tests/ImageProcessing/src/com/android/rs/image/Mirror.java new file mode 100644 index 00000000..b59cb924 --- /dev/null +++ b/java/tests/ImageProcessing/src/com/android/rs/image/Mirror.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.image; + +import java.lang.Math; + +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.Script; +import android.renderscript.ScriptC; +import android.renderscript.Type; +import android.util.Log; + +public class Mirror extends TestBase { + private ScriptC_mirror mScript; + private int mWidth; + private int mHeight; + + public void createTest(android.content.res.Resources res) { + mScript = new ScriptC_mirror(mRS); + + mWidth = mInPixelsAllocation.getType().getX(); + mHeight = mInPixelsAllocation.getType().getY(); + + mScript.set_gIn(mInPixelsAllocation); + mScript.set_gWidth(mWidth); + mScript.set_gHeight(mHeight); + } + + public void runTest() { + mScript.forEach_mirror(mOutPixelsAllocation); + } + +} diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/Resize.java b/java/tests/ImageProcessing/src/com/android/rs/image/Resize.java index 86e16456..85038f79 100644 --- a/java/tests/ImageProcessing/src/com/android/rs/image/Resize.java +++ b/java/tests/ImageProcessing/src/com/android/rs/image/Resize.java @@ -74,7 +74,6 @@ public class Resize extends TestBase { mIntrinsic.forEach_bicubic(mOutPixelsAllocation); } else { mScript.forEach_bicubic(mOutPixelsAllocation); - //mScript.forEach_nearest(mOutPixelsAllocation); } } diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/mirror.rs b/java/tests/ImageProcessing/src/com/android/rs/image/mirror.rs new file mode 100644 index 00000000..6a075d02 --- /dev/null +++ b/java/tests/ImageProcessing/src/com/android/rs/image/mirror.rs @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ip.rsh" +#pragma rs_fp_relaxed + +int32_t gWidth; +int32_t gHeight; +rs_allocation gIn; + +uchar4 RS_KERNEL mirror(uint32_t x, uint32_t y) { + uint32_t x0 = gWidth-x-1; + uchar4 p = rsGetElementAt_uchar4(gIn, x0, y); + return p; +} diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/resize.rs b/java/tests/ImageProcessing/src/com/android/rs/image/resize.rs index ec283bea..101d282d 100644 --- a/java/tests/ImageProcessing/src/com/android/rs/image/resize.rs +++ b/java/tests/ImageProcessing/src/com/android/rs/image/resize.rs @@ -86,7 +86,7 @@ uchar4 __attribute__((kernel)) bicubic(uint32_t x, uint32_t y) { float4 p3 = cubicInterpolate(p30, p31, p32, p33, xf); float4 p = cubicInterpolate(p0, p1, p2, p3, yf); - p = clamp(p, 0.f, 255.f); + p = clamp(p + 0.5f, 0.f, 255.f); return convert_uchar4(p); } diff --git a/java/tests/ImageProcessing_jb/Android.mk b/java/tests/ImageProcessing_jb/Android.mk index 65925b80..4893be9d 100644 --- a/java/tests/ImageProcessing_jb/Android.mk +++ b/java/tests/ImageProcessing_jb/Android.mk @@ -17,6 +17,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +LOCAL_JAVA_LIBRARIES := android.test.runner + LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := $(call all-java-files-under, src) \ diff --git a/java/tests/ImageProcessing_jb/AndroidManifest.xml b/java/tests/ImageProcessing_jb/AndroidManifest.xml index 7d428839..5720ff71 100644 --- a/java/tests/ImageProcessing_jb/AndroidManifest.xml +++ b/java/tests/ImageProcessing_jb/AndroidManifest.xml @@ -3,9 +3,10 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.rs.imagejb"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - <uses-sdk android:minSdkVersion="11" /> - <application android:label="IP-18" - android:hardwareAccelerated="true"> + <uses-sdk android:minSdkVersion="18" /> + <application android:label="ImageProcessing" + android:hardwareAccelerated="true" + android:theme="@android:style/Theme.Holo.Light"> <activity android:name="ImageProcessingActivityJB"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/java/tests/ImageProcessing_jb/res/drawable-hdpi/ic_action_settings.png b/java/tests/ImageProcessing_jb/res/drawable-hdpi/ic_action_settings.png Binary files differnew file mode 100644 index 00000000..54eecded --- /dev/null +++ b/java/tests/ImageProcessing_jb/res/drawable-hdpi/ic_action_settings.png diff --git a/java/tests/ImageProcessing_jb/res/drawable-mdpi/ic_action_settings.png b/java/tests/ImageProcessing_jb/res/drawable-mdpi/ic_action_settings.png Binary files differnew file mode 100644 index 00000000..25c36db4 --- /dev/null +++ b/java/tests/ImageProcessing_jb/res/drawable-mdpi/ic_action_settings.png diff --git a/java/tests/ImageProcessing_jb/res/drawable-xhdpi/ic_action_settings.png b/java/tests/ImageProcessing_jb/res/drawable-xhdpi/ic_action_settings.png Binary files differnew file mode 100644 index 00000000..425a8bc8 --- /dev/null +++ b/java/tests/ImageProcessing_jb/res/drawable-xhdpi/ic_action_settings.png diff --git a/java/tests/ImageProcessing_jb/res/drawable-xxhdpi/ic_action_settings.png b/java/tests/ImageProcessing_jb/res/drawable-xxhdpi/ic_action_settings.png Binary files differnew file mode 100644 index 00000000..fe5fec47 --- /dev/null +++ b/java/tests/ImageProcessing_jb/res/drawable-xxhdpi/ic_action_settings.png diff --git a/java/tests/ImageProcessing_jb/res/layout/controls.xml b/java/tests/ImageProcessing_jb/res/layout/controls.xml index 0e89dd9e..a77fd6b0 100644 --- a/java/tests/ImageProcessing_jb/res/layout/controls.xml +++ b/java/tests/ImageProcessing_jb/res/layout/controls.xml @@ -20,47 +20,6 @@ android:layout_height="fill_parent" android:id="@+id/toplevel"> - <Spinner - android:id="@+id/image_size" - android:layout_width="fill_parent" - android:layout_height="wrap_content"/> - - <LinearLayout - android:orientation="horizontal" - android:layout_width="fill_parent" android:layout_height="wrap_content"> - <ToggleButton android:id="@+id/io_control" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColorLink="@android:color/holo_blue_light" - android:textOff="@string/io_control_on" - android:textOn="@string/io_control_off" - android:textSize="12dp"/> - <ToggleButton - android:id="@+id/length_control" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColorLink="@android:color/holo_blue_light" - android:textOff="@string/length_long" - android:textOn="@string/length_short" - android:textSize="12dp"/> - <ToggleButton - android:id="@+id/background_work" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColorLink="@android:color/holo_blue_light" - android:textOff="@string/dvfs_on" - android:textOn="@string/dvfs_off" - android:textSize="12dp"/> - <ToggleButton - android:id="@+id/pause" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColorLink="@android:color/holo_blue_light" - android:textOff="@string/pause_on" - android:textOn="@string/pause_off" - android:textSize="12dp"/> - </LinearLayout> - <ListView android:id="@+id/test_list" android:layout_weight="0.2" @@ -71,49 +30,25 @@ android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button - android:id="@+id/select_all" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/select_all" - android:textSize="12dp" - android:onClick="btnSelAll"/> - <Button - android:id="@+id/select_none" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/select_none" - android:textSize="12dp" - android:onClick="btnSelNone"/> - <Button - android:id="@+id/select_hp" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/select_hp" - android:textSize="12dp" - android:onClick="btnSelHp"/> + android:id="@+id/run" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/benchmark" + android:onClick="btnRun"/> <Button - android:id="@+id/select_lp" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/select_lp" - android:textSize="12dp" - android:onClick="btnSelLp"/> + android:id="@+id/select_all" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/select_all" + android:onClick="btnSelAll"/> <Button - android:id="@+id/select_intrinsics" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/select_intrinsics" - android:textSize="12dp" - android:onClick="btnSelIntrinsic"/> + android:id="@+id/select_none" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/select_none" + android:onClick="btnSelNone"/> </LinearLayout> - <Button - android:id="@+id/run" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/benchmark" - android:onClick="btnRun"/> - <TextView android:id="@+id/results" android:layout_width="match_parent" diff --git a/java/tests/ImageProcessing_jb/res/layout/spinner_layout.xml b/java/tests/ImageProcessing_jb/res/layout/spinner_layout.xml index 8196bbf0..7e9590e2 100644 --- a/java/tests/ImageProcessing_jb/res/layout/spinner_layout.xml +++ b/java/tests/ImageProcessing_jb/res/layout/spinner_layout.xml @@ -18,6 +18,6 @@ <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:padding="10dp" - android:textSize="16sp" + android:padding="2sp" + android:textSize="14sp" /> diff --git a/java/tests/ImageProcessing_jb/res/menu/main_activity_actions.xml b/java/tests/ImageProcessing_jb/res/menu/main_activity_actions.xml new file mode 100644 index 00000000..df0159b3 --- /dev/null +++ b/java/tests/ImageProcessing_jb/res/menu/main_activity_actions.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + <item android:id="@+id/action_res" + android:title="@string/action_res" + android:icon="@drawable/ic_action_settings" + android:showAsAction="always" + android:actionViewClass="android.widget.Spinner" /> + + + <item android:id="@+id/action_settings" + android:icon="@drawable/ic_action_settings" + android:title="@string/action_settings" + android:showAsAction="always"/> + +</menu> diff --git a/java/tests/ImageProcessing_jb/res/values/strings.xml b/java/tests/ImageProcessing_jb/res/values/strings.xml index fdaefcd5..5ca8d7c5 100644 --- a/java/tests/ImageProcessing_jb/res/values/strings.xml +++ b/java/tests/ImageProcessing_jb/res/values/strings.xml @@ -31,21 +31,26 @@ <string name="benchmark">Benchmark</string> <string name="results">Results: not run</string> - - <string name="io_control_on">USAGE_IO</string> - <string name="io_control_off">USAGE_IO</string> <string name="length_long">Long run</string> <string name="length_short">Long run</string> - <string name="dvfs_on">Background work</string> - <string name="dvfs_off">Background work</string> - <string name="run_all">Benchmark All</string> - <string name="run_one">Benchmark One</string> <string name="select_all">All</string> <string name="select_none">None</string> - <string name="select_hp">Full FP</string> - <string name="select_lp">Relaxed FP</string> - <string name="pause_on">Pause</string> - <string name="pause_off">Pause</string> - <string name="select_intrinsics">Intrinsics</string> + + <string name="action_settings">Setting</string> + <string name="action_resolution">Resolution</string> + + <string name="action_res">res</string> + <string name="ok">Ok</string> + <string name="cancel">Cancel</string> + <string name="settings">settings</string> + <string-array + name="settings_array"> + <item>Use shared memory (TextureView) for output</item> + <item>Animate paramaters during benchmark</item> + <item>Display output while testing</item> + <item>Simulate background CPU load</item> + <item>Run each test longer, 10 seconds</item> + <item>Pause 10 seconds between tests</item> + </string-array> </resources> diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java index 63c0c9cc..1516ad41 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java @@ -53,7 +53,7 @@ public class Blend extends TestBase { currentIntrinsic = pos; if (mRS != null) { runTest(); - act.updateDisplay(); + act.mProcessor.update(); } } diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25.java index 6d71e9e7..11927625 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25.java @@ -99,20 +99,4 @@ public class Blur25 extends TestBase { mScript.forEach_vert(mOutPixelsAllocation); } } - - public void setupBenchmark() { - if (mUseIntrinsic) { - mIntrinsic.setRadius(MAX_RADIUS); - } else { - mScript.invoke_setRadius(MAX_RADIUS); - } - } - - public void exitBenchmark() { - if (mUseIntrinsic) { - mIntrinsic.setRadius(mRadius); - } else { - mScript.invoke_setRadius((int)mRadius); - } - } } diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java index 6e0cf595..46c0250d 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java @@ -82,14 +82,6 @@ public class Blur25G extends TestBase { mIntrinsic.forEach(mScratchPixelsAllocation2); } - public void setupBenchmark() { - mIntrinsic.setRadius(MAX_RADIUS); - } - - public void exitBenchmark() { - mIntrinsic.setRadius(mRadius); - } - public void updateBitmap(Bitmap b) { mScript.forEach_toU8_4(mScratchPixelsAllocation2, mOutPixelsAllocation); mOutPixelsAllocation.copyTo(b); diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java index e60fee69..86d748ce 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java @@ -58,6 +58,22 @@ public class ColorMatrix extends TestBase { } } + public void animateBars(float time) { + Matrix4f m = new Matrix4f(); + m.set(1, 0, (time + 0.2f) % 1.0f); + m.set(1, 1, (time + 0.9f) % 1.0f); + m.set(1, 2, (time + 0.4f) % 1.0f); + if (mUseIntrinsic) { + if (mUseGrey) { + return; + } else { + mIntrinsic.setColorMatrix(m); + } + } else { + mScript.invoke_setMatrix(m); + } + } + public void runTest() { if (mUseIntrinsic) { mIntrinsic.forEach(mInPixelsAllocation, mOutPixelsAllocation); diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java index 7d9ad35e..301d344a 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java @@ -40,15 +40,26 @@ public class Convolve3x3 extends TestBase { mUseIntrinsic = useIntrinsic; } + private float blend(float v1, float v2, float p) { + return (v2 * p) + (v1 * (1.f-p)); + } + + private float[] updateMatrix(float str) { + float f[] = new float[9]; + float cf1 = blend(1.f / 9.f, 0.f, str); + float cf2 = blend(1.f / 9.f, -1.f, str); + float cf3 = blend(1.f / 9.f, 5.f, str); + f[0] = cf1; f[1] = cf2; f[2] = cf1; + f[3] = cf2; f[4] = cf3; f[5] = cf2; + f[6] = cf1; f[7] = cf2; f[8] = cf1; + return f; + } + public void createTest(android.content.res.Resources res) { mWidth = mInPixelsAllocation.getType().getX(); mHeight = mInPixelsAllocation.getType().getY(); - float f[] = new float[9]; - f[0] = 0.f; f[1] = -1.f; f[2] = 0.f; - f[3] = -1.f; f[4] = 5.f; f[5] = -1.f; - f[6] = 0.f; f[7] = -1.f; f[8] = 0.f; - + float f[] = updateMatrix(1.f); if (mUseIntrinsic) { mIntrinsic = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS)); mIntrinsic.setCoefficients(f); @@ -62,6 +73,15 @@ public class Convolve3x3 extends TestBase { } } + public void animateBars(float time) { + float f[] = updateMatrix(time % 1.f); + if (mUseIntrinsic) { + mIntrinsic.setCoefficients(f); + } else { + mScript.set_gCoeffs(f); + } + } + public void runTest() { if (mUseIntrinsic) { mIntrinsic.forEach(mOutPixelsAllocation); diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java index 6b0ef8c1..6a627f53 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java @@ -40,11 +40,33 @@ public class Convolve5x5 extends TestBase { mUseIntrinsic = useIntrinsic; } + private float blend(float v1, float v2, float p) { + return (v2 * p) + (v1 * (1.f-p)); + } + + private float[] updateMatrix(float str) { + float f[] = new float[25]; + final float f125 = 1.f / 25.f; + float cf1 = blend(f125, -1.f, str); + float cf2 = blend(f125, -3.f, str); + float cf3 = blend(f125, -4.f, str); + float cf4 = blend(f125, 6.f, str); + float cf5 = blend(f125, 20.f, str); + float cf6 = blend(f125, 0.f, str); + f[0] = cf1; f[1] = cf2; f[2] = cf3; f[3] = cf2; f[4] = cf1; + f[5] = cf2; f[6] = cf6; f[7] = cf4; f[8] = cf6; f[9] = cf2; + f[10]= cf3; f[11]= cf4; f[12]= cf5; f[13]= cf4; f[14]= cf3; + f[15]= cf2; f[16]= cf6; f[17]= cf4; f[18]= cf6; f[19]= cf2; + f[20]= cf1; f[21]= cf2; f[22]= cf3; f[23]= cf2; f[24]= cf1; + return f; + } + + public void createTest(android.content.res.Resources res) { mWidth = mInPixelsAllocation.getType().getX(); mHeight = mInPixelsAllocation.getType().getY(); - float f[] = new float[25]; + float f[] = updateMatrix(1.f); //f[0] = 0.012f; f[1] = 0.025f; f[2] = 0.031f; f[3] = 0.025f; f[4] = 0.012f; //f[5] = 0.025f; f[6] = 0.057f; f[7] = 0.075f; f[8] = 0.057f; f[9] = 0.025f; //f[10]= 0.031f; f[11]= 0.075f; f[12]= 0.095f; f[13]= 0.075f; f[14]= 0.031f; @@ -57,12 +79,6 @@ public class Convolve5x5 extends TestBase { //f[15]= 4.f; f[16]= 8.f; f[17]= 0.f; f[18]= -8.f; f[19]= -4.f; //f[20]= 1.f; f[21]= 2.f; f[22]= 0.f; f[23]= -2.f; f[24]= -1.f; - f[0] = -1.f; f[1] = -3.f; f[2] = -4.f; f[3] = -3.f; f[4] = -1.f; - f[5] = -3.f; f[6] = 0.f; f[7] = 6.f; f[8] = 0.f; f[9] = -3.f; - f[10]= -4.f; f[11]= 6.f; f[12]= 20.f; f[13]= 6.f; f[14]= -4.f; - f[15]= -3.f; f[16]= 0.f; f[17]= 6.f; f[18]= 0.f; f[19]= -3.f; - f[20]= -1.f; f[21]= -3.f; f[22]= -4.f; f[23]= -3.f; f[24]= -1.f; - if (mUseIntrinsic) { mIntrinsic = ScriptIntrinsicConvolve5x5.create(mRS, Element.U8_4(mRS)); mIntrinsic.setCoefficients(f); @@ -76,6 +92,15 @@ public class Convolve5x5 extends TestBase { } } + public void animateBars(float time) { + float f[] = updateMatrix(time % 1.f); + if (mUseIntrinsic) { + mIntrinsic.setCoefficients(f); + } else { + mScript.set_gCoeffs(f); + } + } + public void runTest() { if (mUseIntrinsic) { mIntrinsic.forEach(mOutPixelsAllocation); diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Fisheye.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Fisheye.java index 012c60db..4ded8c5d 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Fisheye.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Fisheye.java @@ -71,6 +71,11 @@ public class Fisheye extends TestBase { do_init(); } + public void animateBars(float time) { + scale = time % 2.f; + do_init(); + } + private void do_init() { if (approx) { if (relaxed) diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Grain.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Grain.java index 31e5f79f..02d72f97 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Grain.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Grain.java @@ -45,6 +45,11 @@ public class Grain extends TestBase { mScript.set_gNoiseStrength(s); } + public void animateBars(float time) { + mScript.set_gNoiseStrength(time % 1.f); + } + + private int findHighBit(int v) { int bit = 0; while (v > 1) { @@ -89,6 +94,5 @@ public class Grain extends TestBase { mScript.forEach_blend9(mNoise2); mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation); } - } diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/GroupTest.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/GroupTest.java index 3e5175ab..ff1e1ff5 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/GroupTest.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/GroupTest.java @@ -79,6 +79,14 @@ public class GroupTest extends TestBase { } } + public void animateBars(float time) { + Matrix4f m = new Matrix4f(); + m.set(1, 0, (time + 0.2f) % 1.0f); + m.set(1, 1, (time + 0.9f) % 1.0f); + m.set(1, 2, (time + 0.4f) % 1.0f); + mMatrix.setColorMatrix(m); + } + public void runTest() { mConvolve.setInput(mInPixelsAllocation); if (mUseNative) { diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java index 911736f3..a38bc847 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java @@ -16,11 +16,13 @@ package com.android.rs.imagejb; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MenuInflater; + import android.app.Activity; import android.os.Bundle; import android.os.Handler; -import android.os.Message; -import android.graphics.Canvas; import android.graphics.Point; import android.view.SurfaceView; import android.widget.AdapterView; @@ -48,7 +50,6 @@ public class IPControlsJB extends Activity { private final String TAG = "Img"; public final String RESULT_FILE = "image_processing_result.csv"; - private ToggleButton mIOButton; private Spinner mResSpinner; private ListView mTestListView; private TextView mResultView; @@ -56,10 +57,13 @@ public class IPControlsJB extends Activity { private ArrayAdapter<String> mTestListAdapter; private ArrayList<String> mTestList = new ArrayList<String>(); - private boolean mToggleIO = false; - private boolean mToggleDVFS = false; - private boolean mToggleLong = false; - private boolean mTogglePause = false; + private boolean mSettings[] = {true, true, true, false, false, false}; + private static final int SETTING_USE_IO = 0; + private static final int SETTING_ANIMATE = 1; + private static final int SETTING_DISPLAY = 2; + private static final int SETTING_USE_DVFS = 3; + private static final int SETTING_LONG_RUN = 4; + private static final int SETTING_PAUSE = 5; private float mResults[]; @@ -86,6 +90,34 @@ public class IPControlsJB extends Activity { } private Resolutions mRes; + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu items for use in the action bar + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_activity_actions, menu); + + MenuItem searchItem = menu.findItem(R.id.action_res); + mResSpinner = (Spinner) searchItem.getActionView(); + + mResSpinner.setOnItemSelectedListener(mResSpinnerListener); + mResSpinner.setAdapter(new ArrayAdapter<Resolutions>( + this, R.layout.spinner_layout, Resolutions.values())); + + // Choose one of the image sizes that close to the resolution + // of the screen. + Point size = new Point(); + getWindowManager().getDefaultDisplay().getSize(size); + int md = (size.x > size.y) ? size.x : size.y; + for (int ct=0; ct < Resolutions.values().length; ct++) { + if (Resolutions.values()[ct].width <= (int)(md * 1.2)) { + mResSpinner.setSelection(ct); + break; + } + } + + return super.onCreateOptionsMenu(menu); + } + private AdapterView.OnItemSelectedListener mResSpinnerListener = new AdapterView.OnItemSelectedListener() { @@ -97,13 +129,19 @@ public class IPControlsJB extends Activity { } }; - void init() { - mIOButton = (ToggleButton) findViewById(R.id.io_control); + void launchDemo(int id) { + IPTestListJB.TestName t[] = IPTestListJB.TestName.values(); - mResSpinner = (Spinner) findViewById(R.id.image_size); - mResSpinner.setOnItemSelectedListener(mResSpinnerListener); - mResSpinner.setAdapter(new ArrayAdapter<Resolutions>( - this, R.layout.spinner_layout, Resolutions.values())); + int testList[] = new int[1]; + testList[0] = id; + + Intent intent = makeBasicLaunchIntent(); + intent.putExtra("tests", testList); + intent.putExtra("demo", true); + startActivityForResult(intent, 0); + } + + void init() { for (int i=0; i < IPTestListJB.TestName.values().length; i++) { mTestList.add(IPTestListJB.TestName.values()[i].toString()); @@ -118,51 +156,15 @@ public class IPControlsJB extends Activity { mTestListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); mTestListAdapter.notifyDataSetChanged(); - ToggleButton toggle; - toggle = (ToggleButton) findViewById(R.id.io_control); - toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mToggleIO = isChecked; - } - }); - toggle.setChecked(mToggleIO); - - toggle = (ToggleButton) findViewById(R.id.length_control); - toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mToggleLong = isChecked; - } - }); - toggle.setChecked(mToggleLong); - - toggle = (ToggleButton) findViewById(R.id.background_work); - toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mToggleDVFS = isChecked; - } - }); - toggle.setChecked(mToggleDVFS); - - toggle = (ToggleButton) findViewById(R.id.pause); - toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mTogglePause = isChecked; - } - }); - toggle.setChecked(mTogglePause); - mResultView = (TextView) findViewById(R.id.results); - - Point size = new Point(); - getWindowManager().getDefaultDisplay().getSize(size); - int md = (size.x > size.y) ? size.x : size.y; - for (int ct=0; ct < Resolutions.values().length; ct++) { - if (Resolutions.values()[ct].width <= (int)(md * 1.2)) { - mResSpinner.setSelection(ct); - break; - } - } + mTestListView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { + public boolean onItemLongClick(AdapterView<?> arg0, View arg1, + int pos, long id) { + launchDemo(pos); + return true; + } + }); } @Override @@ -194,6 +196,19 @@ public class IPControlsJB extends Activity { } } + Intent makeBasicLaunchIntent() { + Intent intent = new Intent(this, ImageProcessingActivityJB.class); + intent.putExtra("enable io", mSettings[SETTING_USE_IO]); + intent.putExtra("enable dvfs", mSettings[SETTING_USE_DVFS]); + intent.putExtra("enable long", mSettings[SETTING_LONG_RUN]); + intent.putExtra("enable pause", mSettings[SETTING_PAUSE]); + intent.putExtra("enable animate", mSettings[SETTING_ANIMATE]); + intent.putExtra("enable display", mSettings[SETTING_DISPLAY]); + intent.putExtra("resolution X", mRes.width); + intent.putExtra("resolution Y", mRes.height); + return intent; + } + public void btnRun(View v) { IPTestListJB.TestName t[] = IPTestListJB.TestName.values(); @@ -215,14 +230,8 @@ public class IPControlsJB extends Activity { } } - Intent intent = new Intent(this, ImageProcessingActivityJB.class); + Intent intent = makeBasicLaunchIntent(); intent.putExtra("tests", testList); - intent.putExtra("enable io", mToggleIO); - intent.putExtra("enable dvfs", mToggleDVFS); - intent.putExtra("enable long", mToggleLong); - intent.putExtra("enable pause", mTogglePause); - intent.putExtra("resolution X", mRes.width); - intent.putExtra("resolution Y", mRes.height); startActivityForResult(intent, 0); } @@ -307,6 +316,18 @@ public class IPControlsJB extends Activity { } } + public boolean onOptionsItemSelected(MenuItem item) { + // Handle presses on the action bar items + switch(item.getItemId()) { + case R.id.action_settings: + IPSettings newFragment = new IPSettings(mSettings); + newFragment.show(getFragmentManager(), "settings"); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + public void btnSelNone(View v) { checkGroup(-1); } @@ -319,6 +340,11 @@ public class IPControlsJB extends Activity { checkGroup(1); } + public void btnSettings(View v) { + IPSettings newFragment = new IPSettings(mSettings); + newFragment.show(getFragmentManager(), "settings"); + } + public void btnSelIntrinsic(View v) { checkGroup(2); } diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPSettings.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPSettings.java new file mode 100644 index 00000000..d9b9c31b --- /dev/null +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPSettings.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.imagejb; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DialogFragment; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.View; + +public class IPSettings extends DialogFragment { + private boolean[] mEnables; + public boolean mOk = false; + + public IPSettings(boolean[] enables) { + mEnables = enables; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.settings); + + // Specify the list array, the items to be selected by default (null for none), + // and the listener through which to receive callbacks when items are selected + builder.setMultiChoiceItems(R.array.settings_array, mEnables, + new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, boolean isChecked) { + mEnables[which] = isChecked; + } + }); + + // Set the action buttons + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + mOk = true; + } + }); + builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + } + }); + + return builder.create(); + } +} diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java index 398f9c13..b03171fe 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java @@ -32,48 +32,50 @@ public class IPTestListJB { * Define enum type for test names */ public enum TestName { - LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed", RELAXED_FP, 55.6f), - LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed", RELAXED_FP, 39.1f), - LEVELS_VEC3_FULL ("Levels Vec3 Full", FULL_FP, 57.4f), - LEVELS_VEC4_FULL ("Levels Vec4 Full", FULL_FP, 68.1f), - BLUR_RADIUS_25 ("Blur radius 25", RELAXED_FP, 1045.f), - INTRINSIC_BLUR_RADIUS_25 ("Intrinsic Blur radius 25", INTRINSIC, 643.f), - GREYSCALE ("Greyscale", RELAXED_FP, 38.3f), - GRAIN ("Grain", RELAXED_FP, 57.8f), - FISHEYE_FULL ("Fisheye Full", FULL_FP, 211.2f), - FISHEYE_RELAXED ("Fisheye Relaxed", RELAXED_FP, 198.1f), - FISHEYE_APPROXIMATE_FULL ("Fisheye Approximate Full", FULL_FP, 211.0f), - FISHEYE_APPROXIMATE_RELAXED ("Fisheye Approximate Relaxed", RELAXED_FP, 190.1f), - VIGNETTE_FULL ("Vignette Full", FULL_FP, 98.6f), - VIGNETTE_RELAXED ("Vignette Relaxed", RELAXED_FP, 110.7f), - VIGNETTE_APPROXIMATE_FULL ("Vignette Approximate Full", FULL_FP, 80.6f), - VIGNETTE_APPROXIMATE_RELAXED ("Vignette Approximate Relaxed", RELAXED_FP, 87.9f), - GROUP_TEST_EMULATED ("Group Test (emulated)", INTRINSIC, 37.81f), - GROUP_TEST_NATIVE ("Group Test (native)", INTRINSIC, 37.8f), - CONVOLVE_3X3 ("Convolve 3x3", RELAXED_FP, 62.1f), - INTRINSICS_CONVOLVE_3X3 ("Intrinsics Convolve 3x3", INTRINSIC, 24.5f), - COLOR_MATRIX ("ColorMatrix", RELAXED_FP, 25.5f), - INTRINSICS_COLOR_MATRIX ("Intrinsics ColorMatrix", INTRINSIC, 13.3f), - INTRINSICS_COLOR_MATRIX_GREY ("Intrinsics ColorMatrix Grey", INTRINSIC, 13.4f), - COPY ("Copy", RELAXED_FP, 25.6f), - CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)", INTRINSIC, 18.6f), - CONVOLVE_5X5 ("Convolve 5x5", RELAXED_FP, 215.8f), - INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5", INTRINSIC, 29.8f), - MANDELBROT_FLOAT ("Mandelbrot (fp32)", FULL_FP, 108.1f), - MANDELBROT_DOUBLE ("Mandelbrot (fp64)", FULL_FP, 108.1f), - INTRINSICS_BLEND ("Intrinsics Blend", INTRINSIC, 94.2f), - INTRINSICS_BLUR_25G ("Intrinsics Blur 25 uchar", INTRINSIC, 173.3f), - VIBRANCE ("Vibrance", RELAXED_FP, 88.3f), - BW_FILTER ("BW Filter", RELAXED_FP, 69.7f), - SHADOWS ("Shadows", RELAXED_FP, 155.3f), - CONTRAST ("Contrast", RELAXED_FP, 27.0f), - EXPOSURE ("Exposure", RELAXED_FP, 64.7f), - WHITE_BALANCE ("White Balance", RELAXED_FP, 160.1f), - COLOR_CUBE ("Color Cube", RELAXED_FP, 85.3f), - COLOR_CUBE_3D_INTRINSIC ("Color Cube (3D LUT intrinsic)", INTRINSIC, 49.5f), - ARTISTIC1 ("Artistic 1", RELAXED_FP, 120.f), - RESIZE_BI_SCRIPT ("Resize BiCubic Script", RELAXED_FP, 100.f), - RESIZE_BI_INTRINSIC ("Resize BiCubic Intrinsic", INTRINSIC, 100.f); + LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed", RELAXED_FP, 61.1f), + LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed", RELAXED_FP, 44.6f), + LEVELS_VEC3_FULL ("Levels Vec3 Full", FULL_FP, 61.9f), + LEVELS_VEC4_FULL ("Levels Vec4 Full", FULL_FP, 73.f), + BLUR_RADIUS_25 ("Blur radius 25", RELAXED_FP, 1103.f), + INTRINSIC_BLUR_RADIUS_25 ("Intrinsic Blur radius 25", INTRINSIC, 176.f), + GREYSCALE ("Greyscale", RELAXED_FP, 43.7f), + GRAIN ("Grain", RELAXED_FP, 147.4f), + FISHEYE_FULL ("Fisheye Full", FULL_FP, 192.f), + FISHEYE_RELAXED ("Fisheye Relaxed", RELAXED_FP, 181.f), + FISHEYE_APPROXIMATE_FULL ("Fisheye Approximate Full", FULL_FP, 193.f), + FISHEYE_APPROXIMATE_RELAXED ("Fisheye Approximate Relaxed", RELAXED_FP, 183.f), + VIGNETTE_FULL ("Vignette Full", FULL_FP, 101.f), + VIGNETTE_RELAXED ("Vignette Relaxed", RELAXED_FP, 116.f), + VIGNETTE_APPROXIMATE_FULL ("Vignette Approximate Full", FULL_FP, 85.1f), + VIGNETTE_APPROXIMATE_RELAXED ("Vignette Approximate Relaxed", RELAXED_FP, 96.7f), + GROUP_TEST_EMULATED ("Group Test (emulated)", INTRINSIC, 51.7f), + GROUP_TEST_NATIVE ("Group Test (native)", INTRINSIC, 52.9f), + CONVOLVE_3X3 ("Convolve 3x3", RELAXED_FP, 74.2f), + INTRINSICS_CONVOLVE_3X3 ("Intrinsics Convolve 3x3", INTRINSIC, 33.3f), + COLOR_MATRIX ("ColorMatrix", RELAXED_FP, 33.8f), + INTRINSICS_COLOR_MATRIX ("Intrinsics ColorMatrix", INTRINSIC, 21.3f), + INTRINSICS_COLOR_MATRIX_GREY ("Intrinsics ColorMatrix Grey", INTRINSIC, 21.4f), + COPY ("Copy", RELAXED_FP, 21.4f), + CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)", INTRINSIC, 23.1f), + CONVOLVE_5X5 ("Convolve 5x5", RELAXED_FP, 236.f), + INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5", INTRINSIC, 39.6f), + MANDELBROT_FLOAT ("Mandelbrot (fp32)", FULL_FP, 117.f), + MANDELBROT_DOUBLE ("Mandelbrot (fp64)", FULL_FP, 136.f), + INTRINSICS_BLEND ("Intrinsics Blend", INTRINSIC, 105.f), + INTRINSICS_BLUR_25G ("Intrinsics Blur 25 uchar", INTRINSIC, 37.8f), + VIBRANCE ("Vibrance", RELAXED_FP, 103.f), + BW_FILTER ("BW Filter", RELAXED_FP, 86.f), + SHADOWS ("Shadows", RELAXED_FP, 130.f), + CONTRAST ("Contrast", RELAXED_FP, 45.4f), + EXPOSURE ("Exposure", RELAXED_FP, 73.4f), + WHITE_BALANCE ("White Balance", RELAXED_FP, 138.2f), + COLOR_CUBE ("Color Cube", RELAXED_FP, 83.9f), + COLOR_CUBE_3D_INTRINSIC ("Color Cube (3D LUT intrinsic)", INTRINSIC, 34.7f), + ARTISTIC1 ("Artistic 1", RELAXED_FP, 140.f), + RESIZE_BI_SCRIPT ("Resize BiCubic Script", RELAXED_FP, 253.f), + RESIZE_BI_INTRINSIC ("Resize BiCubic Intrinsic", INTRINSIC, 255.f), + POSTERIZE_INVOKE ("Posterize with invoke", RELAXED_FP, 215.f), + POSTERIZE_SET ("Posterize with set", INTRINSIC, 221.f); private final String name; @@ -183,6 +185,10 @@ public class IPTestListJB { return new Resize(false); case RESIZE_BI_INTRINSIC: return new Resize(true); + case POSTERIZE_INVOKE: + return new Posterize(true); + case POSTERIZE_SET: + return new Posterize(false); } return null; } diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java index 6d8ecb06..e49e9cc8 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java @@ -17,6 +17,7 @@ package com.android.rs.imagejb; import android.app.Activity; + import android.content.Intent; import android.os.Bundle; import android.os.Handler; @@ -52,6 +53,10 @@ public class ImageProcessingActivityJB extends Activity private SeekBar mBar3; private SeekBar mBar4; private SeekBar mBar5; + + private int mBars[] = new int[5]; + private int mBarsOld[] = new int[5]; + private TextView mText1; private TextView mText2; private TextView mText3; @@ -66,8 +71,27 @@ public class ImageProcessingActivityJB extends Activity private boolean mToggleDVFS; private boolean mToggleLong; private boolean mTogglePause; + private boolean mToggleAnimate; + private boolean mToggleDisplay; private int mBitmapWidth; private int mBitmapHeight; + private boolean mDemoMode; + + // Updates pending is a counter of how many kernels have been + // sent to RS for processing + // + // In benchmark this is incremented each time a kernel is launched and + // decremented each time a kernel completes + // + // In demo mode, each UI input increments the counter and it is zeroed + // when the latest settings are sent to RS for processing. + private int mUpdatesPending; + + // In demo mode this is used to count updates in the pipeline. It's + // incremented when work is submitted to RS and decremented when invalidate is + // called to display a result. + private int mShowsPending; + static public class SizedTV extends TextureView { int mWidth; @@ -98,6 +122,28 @@ public class ImageProcessingActivityJB extends Activity ///////////////////////////////////////////////////////////////////////// + // Message processor to handle notifications for when kernel completes + private class MessageProcessor extends RenderScript.RSMessageHandler { + MessageProcessor() { + } + + public void run() { + synchronized(mProcessor) { + // In demo mode, decrement the pending displays and notify the + // UI processor it can now enqueue more work if additional updates + // are blocked by a full pipeline. + if (mShowsPending > 0) { + mShowsPending --; + mProcessor.notifyAll(); + } + } + } + } + + + ///////////////////////////////////////////////////////////////////////// + // Processor is a helper thread for running the work without + // blocking the UI thread. class Processor extends Thread { RenderScript mRS; Allocation mInPixelsAllocation; @@ -108,17 +154,45 @@ public class ImageProcessingActivityJB extends Activity private Surface mOutSurface; private float mLastResult; private boolean mRun = true; - private int mOp = 0; private boolean mDoingBenchmark; private TestBase mTest; private TextureView mDisplayView; private boolean mBenchmarkMode; + // We don't want to call the "changed" methods excessively as this + // can cause extra work for drivers. Before running a test update + // any bars which have changed. + void runTest() { + if (mBars[0] != mBarsOld[0]) { + mTest.onBar1Changed(mBars[0]); + mBarsOld[0] = mBars[0]; + } + if (mBars[1] != mBarsOld[1]) { + mTest.onBar2Changed(mBars[1]); + mBarsOld[1] = mBars[1]; + } + if (mBars[2] != mBarsOld[2]) { + mTest.onBar3Changed(mBars[2]); + mBarsOld[2] = mBars[2]; + } + if (mBars[3] != mBarsOld[3]) { + mTest.onBar4Changed(mBars[3]); + mBarsOld[3] = mBars[3]; + } + if (mBars[4] != mBarsOld[4]) { + mTest.onBar5Changed(mBars[4]); + mBarsOld[4] = mBars[4]; + } + mTest.runTest(); + } + Processor(RenderScript rs, TextureView v, boolean benchmarkMode) { mRS = rs; mDisplayView = v; + mRS.setMessageHandler(new MessageProcessor()); + switch(mBitmapWidth) { case 3840: mInPixelsAllocation = Allocation.createFromBitmapResource( @@ -146,6 +220,8 @@ public class ImageProcessingActivityJB extends Activity break; } + // We create the output allocation using USAGE_IO_OUTPUT so we can share the + // bits with a TextureView. This is more efficient than using a bitmap. mOutDisplayAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(), Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT | @@ -163,82 +239,122 @@ public class ImageProcessingActivityJB extends Activity start(); } + class Result { + float totalTime; + int itterations; + } + + // Run one loop of kernels for at least the specified minimum time. + // The function returns the average time in ms for the test run + private Result runBenchmarkLoop(float minTime) { + mUpdatesPending = 0; + Result r = new Result(); + + long t = java.lang.System.currentTimeMillis(); + do { + synchronized(this) { + // Shows pending is used to track the number of kernels in the RS pipeline + // We throttle it to 2. This provide some buffering to allow a kernel to be started + // before we are nofitied the previous finished. However, larger numbers are uncommon + // in interactive apps as they introduce 'lag' between user input and display. + mShowsPending++; + if (mShowsPending > 2) { + try { + this.wait(); + } catch(InterruptedException e) { + } + } + } + + // If animations are enabled update the test state. + if (mToggleAnimate) { + mTest.animateBars(r.totalTime); + } + + // Run the kernel + mTest.runTest(); + r.itterations ++; + + if (mToggleDisplay) { + // If we are not outputting directly to the TextureView we need to copy from + // our temporary buffer. + if (mOutDisplayAllocation != mOutPixelsAllocation) { + mOutDisplayAllocation.copyFrom(mOutPixelsAllocation); + } + + // queue the update of the TextureView with the allocation contents + mOutDisplayAllocation.ioSend(); + } + + // Send our RS message handler a message so we know when this work has completed + mRS.sendMessage(0, null); + + long t2 = java.lang.System.currentTimeMillis(); + r.totalTime += (t2 - t) / 1000.f; + t = t2; + } while (r.totalTime < minTime); + + // Wait for any stray operations to complete and update the final time + mRS.finish(); + long t2 = java.lang.System.currentTimeMillis(); + r.totalTime += (t2 - t) / 1000.f; + t = t2; + return r; + } + + + // Get a benchmark result for a specific test private float getBenchmark() { mDoingBenchmark = true; + mUpdatesPending = 0; - mTest.setupBenchmark(); long result = 0; - long runtime = 1000; + float runtime = 1.f; if (mToggleLong) { - runtime = 10000; + runtime = 10.f; } if (mToggleDVFS) { mDvfsWar.go(); } - //Log.v("rs", "Warming"); - long t = java.lang.System.currentTimeMillis() + 250; - do { - mTest.runTest(); - mTest.finish(); - } while (t > java.lang.System.currentTimeMillis()); - //mHandler.sendMessage(Message.obtain()); + // We run a short bit of work before starting the actual test + // this is to let any power management do its job and respond + runBenchmarkLoop(0.3f); - //Log.v("rs", "Benchmarking"); - int ct = 0; - t = java.lang.System.currentTimeMillis(); - do { - mTest.runTest(); - mTest.finish(); - ct++; - } while ((t + runtime) > java.lang.System.currentTimeMillis()); - t = java.lang.System.currentTimeMillis() - t; - float ft = (float)t; - ft /= ct; - - mTest.exitBenchmark(); - mDoingBenchmark = false; + // Run the actual benchmark + Result r = runBenchmarkLoop(runtime); - android.util.Log.v("rs", "bench " + ft); - return ft; - } + Log.v("rs", "Test: time=" + r.totalTime +"s, frames=" + r.itterations + + ", avg=" + r.totalTime / r.itterations * 1000.f); - private Handler mHandler = new Handler() { - // Allow the filter to complete without blocking the UI - // thread. When the message arrives that the op is complete - // we will either mark completion or start a new filter if - // more work is ready. Either way, display the result. - @Override - public void handleMessage(Message msg) { - synchronized(this) { - if (mRS == null || mOutPixelsAllocation == null) { - return; - } - if (mOutDisplayAllocation != mOutPixelsAllocation) { - mOutDisplayAllocation.copyFrom(mOutPixelsAllocation); - } - mOutDisplayAllocation.ioSend(); - mDisplayView.invalidate(); - //mTest.runTestSendMessage(); - } - } - }; + mDoingBenchmark = false; + return r.totalTime / r.itterations * 1000.f; + } public void run() { Surface lastSurface = null; while (mRun) { + // Our loop for launching tests or benchmarks synchronized(this) { - try { - this.wait(); - } catch(InterruptedException e) { + // If we have no work to do, or we have displays pending, wait + if ((mUpdatesPending == 0) || (mShowsPending != 0)) { + try { + this.wait(); + } catch(InterruptedException e) { + } } + + // We may have been asked to exit while waiting if (!mRun) return; + // During startup we may not have a surface yet to display, if + // this is the case, wait. if ((mOutSurface == null) || (mOutPixelsAllocation == null)) { continue; } + // Our display surface changed, set it. if (lastSurface != mOutSurface) { mOutDisplayAllocation.setSurface(mOutSurface); lastSurface = mOutSurface; @@ -246,19 +362,27 @@ public class ImageProcessingActivityJB extends Activity } if (mBenchmarkMode) { + // Loop over the tests we want to benchmark for (int ct=0; (ct < mTestList.length) && mRun; ct++) { - mRS.finish(); + // For reproducibility we wait a short time for any sporadic work + // created by the user touching the screen to launch the test to pass. + // Also allows for things to settle after the test changes. + mRS.finish(); try { sleep(250); } catch(InterruptedException e) { } + // If we just ran a test, we destroy it here to relieve some memory pressure if (mTest != null) { mTest.destroy(); } - mTest = changeTest(mTestList[ct]); + // Select the next test + mTest = changeTest(mTestList[ct], false); + + // If the user selected the "long pause" option, wait if (mTogglePause) { for (int i=0; (i < 100) && mRun; i++) { try { @@ -268,30 +392,57 @@ public class ImageProcessingActivityJB extends Activity } } + // Run the test mTestResults[ct] = getBenchmark(); - mHandler.sendMessage(Message.obtain()); } onBenchmarkFinish(mRun); + } else { + boolean update = false; + synchronized(this) { + // If we have updates to process and are not blocked by pending shows, + // start the next kernel + if ((mUpdatesPending > 0) && (mShowsPending == 0)) { + mUpdatesPending = 0; + update = true; + mShowsPending++; + } + } + + if (update) { + // Run the kernel + runTest(); + + // If we are not outputting directly to the TextureView we need to copy from + // our temporary buffer. + if (mOutDisplayAllocation != mOutPixelsAllocation) { + mOutDisplayAllocation.copyFrom(mOutPixelsAllocation); + } + + // queue the update of the TextureView with the allocation contents + mOutDisplayAllocation.ioSend(); + + // Send our RS message handler a message so we know when this work has completed + mRS.sendMessage(0, null); + } } } } public void update() { + // something UI related has changed, enqueue an update if one is not + // already pending. Wake the worker if needed synchronized(this) { - if (mOp == 0) { - mOp = 2; + if (mUpdatesPending < 2) { + mUpdatesPending++; + notifyAll(); } - notifyAll(); } } public void setSurface(Surface s) { - synchronized(this) { - mOutSurface = s; - notifyAll(); - } - //update(); + mOutSurface = s; + update(); } public void exit() { @@ -311,6 +462,11 @@ public class ImageProcessingActivityJB extends Activity if (mOutPixelsAllocation != mOutDisplayAllocation) { mOutPixelsAllocation.destroy(); } + + if (mTest != null) { + mTest.destroy(); + mTest = null; + } mOutDisplayAllocation.destroy(); mRS.destroy(); @@ -382,39 +538,33 @@ public class ImageProcessingActivityJB extends Activity private boolean mDoingBenchmark; public Processor mProcessor; + TestBase changeTest(IPTestListJB.TestName t, boolean setupUI) { + TestBase tb = IPTestListJB.newTest(t); - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - mDisplayView.invalidate(); + tb.createBaseTest(this); + if (setupUI) { + setupBars(tb); } - }; - - public void updateDisplay() { - mHandler.sendMessage(Message.obtain()); - //mProcessor.update(); + return tb; } - TestBase changeTest(int id) { + TestBase changeTest(int id, boolean setupUI) { IPTestListJB.TestName t = IPTestListJB.TestName.values()[id]; - TestBase tb = IPTestListJB.newTest(t); - tb.createBaseTest(this); - //setupBars(tb); - return tb; + return changeTest(t, setupUI); } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { if (seekBar == mBar1) { - mProcessor.mTest.onBar1Changed(progress); + mBars[0] = progress; } else if (seekBar == mBar2) { - mProcessor.mTest.onBar2Changed(progress); + mBars[1] = progress; } else if (seekBar == mBar3) { - mProcessor.mTest.onBar3Changed(progress); + mBars[2] = progress; } else if (seekBar == mBar4) { - mProcessor.mTest.onBar4Changed(progress); + mBars[3] = progress; } else if (seekBar == mBar5) { - mProcessor.mTest.onBar5Changed(progress); + mBars[4] = progress; } mProcessor.update(); } @@ -516,22 +666,11 @@ public class ImageProcessingActivityJB extends Activity finish(); } - @Override - protected void onResume() { - super.onResume(); - Intent i = getIntent(); - mTestList = i.getIntArrayExtra("tests"); - - mToggleIO = i.getBooleanExtra("enable io", false); - mToggleDVFS = i.getBooleanExtra("enable dvfs", false); - mToggleLong = i.getBooleanExtra("enable long", false); - mTogglePause = i.getBooleanExtra("enable pause", false); - mBitmapWidth = i.getIntExtra("resolution X", 0); - mBitmapHeight = i.getIntExtra("resolution Y", 0); - - mTestResults = new float[mTestList.length]; - hideBars(); + void startProcessor() { + if (!mDemoMode) { + hideBars(); + } Point size = new Point(); getWindowManager().getDefaultDisplay().getSize(size); @@ -561,8 +700,33 @@ public class ImageProcessingActivityJB extends Activity mDisplayView.mHeight = th; //mDisplayView.setTransform(new android.graphics.Matrix()); - mProcessor = new Processor(RenderScript.create(this), mDisplayView, true); + mProcessor = new Processor(RenderScript.create(this), mDisplayView, !mDemoMode); mDisplayView.setSurfaceTextureListener(this); + + if (mDemoMode) { + mProcessor.mTest = changeTest(mTestList[0], true); + } + } + + @Override + protected void onResume() { + super.onResume(); + Intent i = getIntent(); + mTestList = i.getIntArrayExtra("tests"); + + mToggleIO = i.getBooleanExtra("enable io", false); + mToggleDVFS = i.getBooleanExtra("enable dvfs", false); + mToggleLong = i.getBooleanExtra("enable long", false); + mTogglePause = i.getBooleanExtra("enable pause", false); + mToggleAnimate = i.getBooleanExtra("enable animate", false); + mToggleDisplay = i.getBooleanExtra("enable display", false); + mBitmapWidth = i.getIntExtra("resolution X", 0); + mBitmapHeight = i.getIntExtra("resolution Y", 0); + mDemoMode = i.getBooleanExtra("demo", false); + + mTestResults = new float[mTestList.length]; + + startProcessor(); } protected void onDestroy() { diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingTest.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingTest.java new file mode 100644 index 00000000..9a9086b2 --- /dev/null +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingTest.java @@ -0,0 +1,422 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.imagejb; + + +import android.os.Bundle; +import android.util.Log; + +import com.android.rs.imagejb.IPTestListJB.TestName; +import com.android.rs.imagejb.ImageProcessingTestRunner; + +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.LargeTest; + +/** + * ImageProcessing benchmark test. + * To run the test, please use command + * + * adb shell am instrument -e iteration <n> -w com.android.rs.image/.ImageProcessingTestRunner + * + */ +public class ImageProcessingTest extends ActivityInstrumentationTestCase2<ImageProcessingActivityJB> { + private final String TAG = "ImageProcessingTest"; + private final String TEST_NAME = "Testname"; + private final String ITERATIONS = "Iterations"; + private final String BENCHMARK = "Benchmark"; + private static int INSTRUMENTATION_IN_PROGRESS = 2; + private int mIteration; + private ImageProcessingActivityJB mActivity; + + public ImageProcessingTest() { + super(ImageProcessingActivityJB.class); + } + + + protected void prepareTest(int test) { + /* + mActivity.mTestList = new int[1]; + mActivity.mTestList[0] = test; + + mActivity.mBitmapWidth = 1920; + mActivity.mBitmapHeight = 1080; + + mActivity.mTestResults = new float[1]; + + mActivity.startProcessor();*/ + } + + @Override + public void setUp() throws Exception { + super.setUp(); + setActivityInitialTouchMode(false); + mActivity = getActivity(); + ImageProcessingTestRunner mRunner = (ImageProcessingTestRunner) getInstrumentation(); + mIteration = mRunner.mIteration; + assertTrue("please enter a valid iteration value", mIteration > 0); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + } + + class TestAction implements Runnable { + TestName mTestName; + float mResult; + public TestAction(TestName testName) { + mTestName = testName; + } + public void run() { + mActivity.changeTest(mTestName, false); + //mResult = mActivity.getBenchmark(); + Log.v(TAG, "Benchmark for test \"" + mTestName.toString() + "\" is: " + mResult); + synchronized(this) { + this.notify(); + } + } + public float getBenchmark() { + return mResult; + } + } + + // Set the benchmark thread to run on ui thread + // Synchronized the thread such that the test will wait for the benchmark thread to finish + public void runOnUiThread(Runnable action) { + synchronized(action) { + mActivity.runOnUiThread(action); + try { + action.wait(); + } catch (InterruptedException e) { + Log.v(TAG, "waiting for action running on UI thread is interrupted: " + + e.toString()); + } + } + } + + public void runTest(TestAction ta, String testName) { + float sum = 0; + for (int i = 0; i < mIteration; i++) { + runOnUiThread(ta); + float bmValue = ta.getBenchmark(); + Log.v(TAG, "results for iteration " + i + " is " + bmValue); + sum += bmValue; + } + float avgResult = sum/mIteration; + + // post result to INSTRUMENTATION_STATUS + Bundle results = new Bundle(); + results.putString(TEST_NAME, testName); + results.putInt(ITERATIONS, mIteration); + results.putFloat(BENCHMARK, avgResult); + getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results); + } + + // Test case 0: Levels Vec3 Relaxed + @LargeTest + public void testLevelsVec3Relaxed() { + TestAction ta = new TestAction(TestName.LEVELS_VEC3_RELAXED); + runTest(ta, TestName.LEVELS_VEC3_RELAXED.name()); + } + + // Test case 1: Levels Vec4 Relaxed + @LargeTest + public void testLevelsVec4Relaxed() { + TestAction ta = new TestAction(TestName.LEVELS_VEC4_RELAXED); + runTest(ta, TestName.LEVELS_VEC4_RELAXED.name()); + } + + // Test case 2: Levels Vec3 Full + @LargeTest + public void testLevelsVec3Full() { + TestAction ta = new TestAction(TestName.LEVELS_VEC3_FULL); + runTest(ta, TestName.LEVELS_VEC3_FULL.name()); + } + + // Test case 3: Levels Vec4 Full + @LargeTest + public void testLevelsVec4Full() { + TestAction ta = new TestAction(TestName.LEVELS_VEC4_FULL); + runTest(ta, TestName.LEVELS_VEC4_FULL.name()); + } + + // Test case 4: Blur Radius 25 + @LargeTest + public void testBlurRadius25() { + TestAction ta = new TestAction(TestName.BLUR_RADIUS_25); + runTest(ta, TestName.BLUR_RADIUS_25.name()); + } + + // Test case 5: Intrinsic Blur Radius 25 + @LargeTest + public void testIntrinsicBlurRadius25() { + TestAction ta = new TestAction(TestName.INTRINSIC_BLUR_RADIUS_25); + runTest(ta, TestName.INTRINSIC_BLUR_RADIUS_25.name()); + } + + // Test case 6: Greyscale + @LargeTest + public void testGreyscale() { + TestAction ta = new TestAction(TestName.GREYSCALE); + runTest(ta, TestName.GREYSCALE.name()); + } + + // Test case 7: Grain + @LargeTest + public void testGrain() { + TestAction ta = new TestAction(TestName.GRAIN); + runTest(ta, TestName.GRAIN.name()); + } + + // Test case 8: Fisheye Full + @LargeTest + public void testFisheyeFull() { + TestAction ta = new TestAction(TestName.FISHEYE_FULL); + runTest(ta, TestName.FISHEYE_FULL.name()); + } + + // Test case 9: Fisheye Relaxed + @LargeTest + public void testFishEyeRelaxed() { + TestAction ta = new TestAction(TestName.FISHEYE_RELAXED); + runTest(ta, TestName.FISHEYE_RELAXED.name()); + } + + // Test case 10: Fisheye Approximate Full + @LargeTest + public void testFisheyeApproximateFull() { + TestAction ta = new TestAction(TestName.FISHEYE_APPROXIMATE_FULL); + runTest(ta, TestName.FISHEYE_APPROXIMATE_FULL.name()); + } + + // Test case 11: Fisheye Approximate Relaxed + @LargeTest + public void testFisheyeApproximateRelaxed() { + TestAction ta = new TestAction(TestName.FISHEYE_APPROXIMATE_RELAXED); + runTest(ta, TestName.FISHEYE_APPROXIMATE_RELAXED.name()); + } + + // Test case 12: Vignette Full + @LargeTest + public void testVignetteFull() { + TestAction ta = new TestAction(TestName.VIGNETTE_FULL); + runTest(ta, TestName.VIGNETTE_FULL.name()); + } + + // Test case 13: Vignette Relaxed + @LargeTest + public void testVignetteRelaxed() { + TestAction ta = new TestAction(TestName.VIGNETTE_RELAXED); + runTest(ta, TestName.VIGNETTE_RELAXED.name()); + } + + // Test case 14: Vignette Approximate Full + @LargeTest + public void testVignetteApproximateFull() { + TestAction ta = new TestAction(TestName.VIGNETTE_APPROXIMATE_FULL); + runTest(ta, TestName.VIGNETTE_APPROXIMATE_FULL.name()); + } + + // Test case 15: Vignette Approximate Relaxed + @LargeTest + public void testVignetteApproximateRelaxed() { + TestAction ta = new TestAction(TestName.VIGNETTE_APPROXIMATE_RELAXED); + runTest(ta, TestName.VIGNETTE_APPROXIMATE_RELAXED.name()); + } + + // Test case 16: Group Test (emulated) + @LargeTest + public void testGroupTestEmulated() { + TestAction ta = new TestAction(TestName.GROUP_TEST_EMULATED); + runTest(ta, TestName.GROUP_TEST_EMULATED.name()); + } + + // Test case 17: Group Test (native) + @LargeTest + public void testGroupTestNative() { + TestAction ta = new TestAction(TestName.GROUP_TEST_NATIVE); + runTest(ta, TestName.GROUP_TEST_NATIVE.name()); + } + + // Test case 18: Convolve 3x3 + @LargeTest + public void testConvolve3x3() { + TestAction ta = new TestAction(TestName.CONVOLVE_3X3); + runTest(ta, TestName.CONVOLVE_3X3.name()); + } + + // Test case 19: Intrinsics Convolve 3x3 + @LargeTest + public void testIntrinsicsConvolve3x3() { + TestAction ta = new TestAction(TestName.INTRINSICS_CONVOLVE_3X3); + runTest(ta, TestName.INTRINSICS_CONVOLVE_3X3.name()); + } + + // Test case 20: ColorMatrix + @LargeTest + public void testColorMatrix() { + TestAction ta = new TestAction(TestName.COLOR_MATRIX); + runTest(ta, TestName.COLOR_MATRIX.name()); + } + + // Test case 21: Intrinsics ColorMatrix + @LargeTest + public void testIntrinsicsColorMatrix() { + TestAction ta = new TestAction(TestName.INTRINSICS_COLOR_MATRIX); + runTest(ta, TestName.INTRINSICS_COLOR_MATRIX.name()); + } + + // Test case 22: Intrinsics ColorMatrix Grey + @LargeTest + public void testIntrinsicsColorMatrixGrey() { + TestAction ta = new TestAction(TestName.INTRINSICS_COLOR_MATRIX_GREY); + runTest(ta, TestName.INTRINSICS_COLOR_MATRIX_GREY.name()); + } + + // Test case 23: Copy + @LargeTest + public void testCopy() { + TestAction ta = new TestAction(TestName.COPY); + runTest(ta, TestName.COPY.name()); + } + + // Test case 24: CrossProcess (using LUT) + @LargeTest + public void testCrossProcessUsingLUT() { + TestAction ta = new TestAction(TestName.CROSS_PROCESS_USING_LUT); + runTest(ta, TestName.CROSS_PROCESS_USING_LUT.name()); + } + + // Test case 25: Convolve 5x5 + @LargeTest + public void testConvolve5x5() { + TestAction ta = new TestAction(TestName.CONVOLVE_5X5); + runTest(ta, TestName.CONVOLVE_5X5.name()); + } + + // Test case 26: Intrinsics Convolve 5x5 + @LargeTest + public void testIntrinsicsConvolve5x5() { + TestAction ta = new TestAction(TestName.INTRINSICS_CONVOLVE_5X5); + runTest(ta, TestName.INTRINSICS_CONVOLVE_5X5.name()); + } + + // Test case 27: Mandelbrot + @LargeTest + public void testMandelbrot() { + TestAction ta = new TestAction(TestName.MANDELBROT_FLOAT); + runTest(ta, TestName.MANDELBROT_FLOAT.name()); + } + + // Test case 28: Intrinsics Blend + @LargeTest + public void testIntrinsicsBlend() { + TestAction ta = new TestAction(TestName.INTRINSICS_BLEND); + runTest(ta, TestName.INTRINSICS_BLEND.name()); + } + + // Test case 29: Intrinsics Blur 25 uchar + @LargeTest + public void testIntrinsicsBlur25G() { + TestAction ta = new TestAction(TestName.INTRINSICS_BLUR_25G); + runTest(ta, TestName.INTRINSICS_BLUR_25G.name()); + } + + // Test case 30: Vibrance + @LargeTest + public void testVibrance() { + TestAction ta = new TestAction(TestName.VIBRANCE); + runTest(ta, TestName.VIBRANCE.name()); + } + + // Test case 31: BWFilter + @LargeTest + public void testBWFilter() { + TestAction ta = new TestAction(TestName.BW_FILTER); + runTest(ta, TestName.BW_FILTER.name()); + } + + // Test case 32: Shadows + @LargeTest + public void testShadows() { + TestAction ta = new TestAction(TestName.SHADOWS); + runTest(ta, TestName.SHADOWS.name()); + } + + // Test case 33: Contrast + @LargeTest + public void testContrast() { + TestAction ta = new TestAction(TestName.CONTRAST); + runTest(ta, TestName.CONTRAST.name()); + } + + // Test case 34: Exposure + @LargeTest + public void testExposure(){ + TestAction ta = new TestAction(TestName.EXPOSURE); + runTest(ta, TestName.EXPOSURE.name()); + } + + // Test case 35: White Balance + @LargeTest + public void testWhiteBalance() { + TestAction ta = new TestAction(TestName.WHITE_BALANCE); + runTest(ta, TestName.WHITE_BALANCE.name()); + } + + // Test case 36: Color Cube + @LargeTest + public void testColorCube() { + TestAction ta = new TestAction(TestName.COLOR_CUBE); + runTest(ta, TestName.COLOR_CUBE.name()); + } + + // Test case 37: Color Cube (3D Intrinsic) + @LargeTest + public void testColorCube3DIntrinsic() { + TestAction ta = new TestAction(TestName.COLOR_CUBE_3D_INTRINSIC); + runTest(ta, TestName.COLOR_CUBE_3D_INTRINSIC.name()); + } +/* + // Test case 38: Usage io + @LargeTest + public void testUsageIO() { + TestAction ta = new TestAction(TestName.USAGE_IO); + runTest(ta, TestName.USAGE_IO.name()); + } + // Test case 39: Artistic 1 + @LargeTest + public void testArtistic1() { + TestAction ta = new TestAction(TestName.ARTISTIC_1); + runTest(ta, TestName.ARTISTIC_1.name()); + } + + // Test case 40 Histogram + @LargeTest + public void testHistogram() { + TestAction ta = new TestAction(TestName.HISTOGRAM); + runTest(ta, TestName.HISTOGRAM.name()); + } + + // Test case 41: Mandelbrot fp64 + @LargeTest + public void testMandelbrotfp64() { + TestAction ta = new TestAction(TestName.MANDELBROT_DOUBLE); + runTest(ta, TestName.MANDELBROT_DOUBLE.name()); + } +*/ +} diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingTestRunner.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingTestRunner.java new file mode 100644 index 00000000..50657418 --- /dev/null +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingTestRunner.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.imagejb; + +import com.android.rs.imagejb.ImageProcessingTest; +import android.os.Bundle; +import android.test.InstrumentationTestRunner; +import android.test.InstrumentationTestSuite; +import junit.framework.TestSuite; + +/** + * Run the ImageProcessing benchmark test + * adb shell am instrument -e iteration <n> -w com.android.rs.image/.ImageProcessingTestRunner + * + */ +public class ImageProcessingTestRunner extends InstrumentationTestRunner { + public int mIteration = 5; + + @Override + public TestSuite getAllTests() { + TestSuite suite = new InstrumentationTestSuite(this); + suite.addTestSuite(ImageProcessingTest.class); + return suite; + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + String strIteration = (String) icicle.get("iteration"); + if (strIteration != null) { + mIteration = Integer.parseInt(strIteration); + } + } +} diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java index 38298438..e6963922 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java @@ -18,13 +18,7 @@ package com.android.rs.imagejb; import java.lang.Math; -import android.renderscript.Allocation; -import android.renderscript.Element; -import android.renderscript.RenderScript; import android.renderscript.Matrix3f; -import android.renderscript.Script; -import android.renderscript.ScriptC; -import android.renderscript.Type; import android.util.Log; import android.widget.SeekBar; import android.widget.TextView; @@ -140,6 +134,12 @@ public class LevelsV4 extends TestBase { setLevels(); } + public void animateBars(float time) { + mSaturation = time % 2.f; + setSaturation(); + } + + public void createTest(android.content.res.Resources res) { mScriptR = new ScriptC_levels_relaxed(mRS); mScriptF = new ScriptC_levels_full(mRS); diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java index 0b53ddfc..649986d6 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java @@ -18,12 +18,6 @@ package com.android.rs.imagejb; import java.lang.Math; -import android.renderscript.Allocation; -import android.renderscript.Element; -import android.renderscript.RenderScript; -import android.renderscript.Script; -import android.renderscript.ScriptC; -import android.renderscript.Type; import android.util.Log; import android.widget.SeekBar; import android.widget.TextView; diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Posterize.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Posterize.java new file mode 100644 index 00000000..0e949b88 --- /dev/null +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Posterize.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.imagejb; + +import java.lang.Math; + +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.Script; +import android.renderscript.ScriptC; +import android.renderscript.Type; +import android.renderscript.Short4; +import android.util.Log; + +public class Posterize extends TestBase { + private ScriptC_posterize mScript; + boolean mUseInvokes; + + Posterize(boolean useInvoke) { + mUseInvokes = useInvoke; + } + + public void createTest(android.content.res.Resources res) { + mScript = new ScriptC_posterize(mRS); + } + + void setParams(float intensHigh, float intensLow, int r, int g, int b) { + if (mUseInvokes) { + mScript.invoke_setParams(intensHigh, intensLow, + (short)r, (short)g, (short)b); + } else { + mScript.set_intensityLow(intensLow); + mScript.set_intensityHigh(intensHigh); + mScript.set_color(new Short4((short)r, (short)g, (short)b, (short)255)); + } + } + + public void runTest() { + mScript.set_inputImage(mInPixelsAllocation); + setParams(.2f, 0.f, 255, 0, 0); + mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation); + setParams(.4f, 0.2f, 0, 255, 0); + mScript.forEach_root(mOutPixelsAllocation, mOutPixelsAllocation); + setParams(.6f, 0.4f, 0, 0, 255); + mScript.forEach_root(mOutPixelsAllocation, mOutPixelsAllocation); + setParams(.8f, 0.6f, 255, 255, 0); + mScript.forEach_root(mOutPixelsAllocation, mOutPixelsAllocation); + setParams(1.0f, 0.8f, 0, 255, 255); + mScript.forEach_root(mOutPixelsAllocation, mOutPixelsAllocation); + } + +} diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Shadows.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Shadows.java index d246d596..8b069659 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Shadows.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Shadows.java @@ -16,9 +16,6 @@ package com.android.rs.imagejb; -import java.lang.Math; - -import android.renderscript.Allocation; public class Shadows extends TestBase { private ScriptC_shadows mScript; diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java index 3de98097..b2358f5b 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java @@ -18,24 +18,13 @@ package com.android.rs.imagejb; import android.app.Activity; import android.content.Context; -import android.os.Bundle; -import android.graphics.BitmapFactory; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.renderscript.ScriptC; import android.renderscript.RenderScript; -import android.renderscript.Type; import android.renderscript.Allocation; -import android.renderscript.Element; -import android.renderscript.Script; -import android.view.SurfaceView; -import android.view.SurfaceHolder; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; import android.view.View; import android.util.Log; -import java.lang.Math; import android.widget.Spinner; public class TestBase { @@ -47,18 +36,6 @@ public class TestBase { protected Allocation mOutPixelsAllocation; protected ImageProcessingActivityJB act; - private class MessageProcessor extends RenderScript.RSMessageHandler { - ImageProcessingActivityJB mAct; - - MessageProcessor(ImageProcessingActivityJB act) { - mAct = act; - } - - public void run() { - mAct.updateDisplay(); - } - } - // Override to use UI elements public void onBar1Changed(int progress) { } @@ -99,6 +76,9 @@ public class TestBase { return false; } + public void animateBars(float time) { + } + public boolean onSpinner1Setup(Spinner s) { s.setVisibility(View.INVISIBLE); return false; @@ -107,7 +87,6 @@ public class TestBase { public final void createBaseTest(ImageProcessingActivityJB ipact) { act = ipact; mRS = ipact.mProcessor.mRS; - mRS.setMessageHandler(new MessageProcessor(act)); mInPixelsAllocation = ipact.mProcessor.mInPixelsAllocation; mInPixelsAllocation2 = ipact.mProcessor.mInPixelsAllocation2; @@ -124,28 +103,6 @@ public class TestBase { public void runTest() { } - final public void runTestSendMessage() { - runTest(); - mRS.sendMessage(0, null); - } - - public void finish() { - mRS.finish(); - } - public void destroy() { - mRS.setMessageHandler(null); - } - - public void updateBitmap(Bitmap b) { - mOutPixelsAllocation.copyTo(b); - } - - // Override to configure specific benchmark config. - public void setupBenchmark() { - } - - // Override to reset after benchmark. - public void exitBenchmark() { } } diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vibrance.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vibrance.java index 09822a91..67498d09 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vibrance.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vibrance.java @@ -16,10 +16,6 @@ package com.android.rs.imagejb; -import java.lang.Math; - -import android.renderscript.Allocation; - public class Vibrance extends TestBase { private ScriptC_vibrance mScript; diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vignette.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vignette.java index 79843867..ed1d2cde 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vignette.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Vignette.java @@ -16,10 +16,6 @@ package com.android.rs.imagejb; -import android.renderscript.Allocation; -import android.renderscript.Element; -import android.renderscript.Sampler; -import android.renderscript.Type; import android.widget.SeekBar; import android.widget.TextView; @@ -72,6 +68,7 @@ public class Vignette extends TestBase { return true; } + public void onBar1Changed(int progress) { scale = progress / 50.0f; do_init(); @@ -93,6 +90,11 @@ public class Vignette extends TestBase { do_init(); } + public void animateBars(float time) { + scale = time % 2.f; + do_init(); + } + private void do_init() { if (approx) { if (relaxed) diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/WhiteBalance.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/WhiteBalance.java index f15aaf5b..25c4ff9c 100644 --- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/WhiteBalance.java +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/WhiteBalance.java @@ -18,7 +18,6 @@ package com.android.rs.imagejb; import java.lang.Math; -import android.renderscript.Allocation; public class WhiteBalance extends TestBase { private ScriptC_wbalance mScript; diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/posterize.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/posterize.rs new file mode 100644 index 00000000..043ea5e0 --- /dev/null +++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/posterize.rs @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ip.rsh" +#pragma rs_fp_relaxed + +rs_allocation inputImage; + +float intensityLow = 0.f; +float intensityHigh; +uchar4 color; +const static float3 mono = {0.299f, 0.587f, 0.114f}; + +void setParams(float intensHigh, float intensLow, uchar r, uchar g, uchar b) { + intensityLow = intensLow; + intensityHigh = intensHigh; + uchar4 hats = {r, g, b, 255}; + color = hats; +} + +uchar4 RS_KERNEL root(uchar4 v_in, uint32_t x, uint32_t y) { + uchar4 refpix = rsGetElementAt_uchar4(inputImage, x, y); + float pixelIntensity = dot(rsUnpackColor8888(refpix).rgb, mono); + if ((pixelIntensity <= intensityHigh) && (pixelIntensity >= intensityLow)) { + return color; + } else { + return v_in; + } +} + + diff --git a/rsAllocation.cpp b/rsAllocation.cpp index 7dcbdf82..40c73b88 100644 --- a/rsAllocation.cpp +++ b/rsAllocation.cpp @@ -486,7 +486,7 @@ void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) { } #ifndef RS_COMPATIBILITY_LIB -void Allocation::NewBufferListener::onFrameAvailable() { +void Allocation::NewBufferListener::onFrameAvailable(const BufferItem& /* item */) { intptr_t ip = (intptr_t)alloc; rsc->sendMessageToClient(&ip, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true); } @@ -498,7 +498,7 @@ void * Allocation::getSurface(const Context *rsc) { sp<IGraphicBufferProducer> bp; sp<IGraphicBufferConsumer> bc; BufferQueue::createBufferQueue(&bp, &bc); - mGrallocConsumer = new GrallocConsumer(this, bc); + mGrallocConsumer = new GrallocConsumer(this, bc, mHal.drvState.grallocFlags); bp->incStrong(NULL); mBufferListener = new NewBufferListener(); diff --git a/rsAllocation.h b/rsAllocation.h index f197efc1..065d7be1 100644 --- a/rsAllocation.h +++ b/rsAllocation.h @@ -88,6 +88,8 @@ public: uint32_t shift; uint32_t step; } yuv; + + int grallocFlags; }; mutable DrvState drvState; @@ -183,7 +185,7 @@ protected: const android::renderscript::Context *rsc; const android::renderscript::Allocation *alloc; - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); }; sp<NewBufferListener> mBufferListener; diff --git a/rsGrallocConsumer.cpp b/rsGrallocConsumer.cpp index c5d37b24..3239365d 100644 --- a/rsGrallocConsumer.cpp +++ b/rsGrallocConsumer.cpp @@ -30,11 +30,16 @@ namespace android { namespace renderscript { -GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq) : +GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags) : ConsumerBase(bq, true) { mAlloc = a; - mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN); + if (flags == 0) { + flags = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_RENDERSCRIPT; + } else { + flags |= GRALLOC_USAGE_RENDERSCRIPT; + } + mConsumer->setConsumerUsageBits(flags); mConsumer->setMaxAcquiredBufferCount(2); uint32_t y = a->mHal.drvState.lod[0].dimY; diff --git a/rsGrallocConsumer.h b/rsGrallocConsumer.h index 9e4fc586..88b44405 100644 --- a/rsGrallocConsumer.h +++ b/rsGrallocConsumer.h @@ -44,7 +44,7 @@ class GrallocConsumer : public ConsumerBase public: typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; - GrallocConsumer(Allocation *, const sp<IGraphicBufferConsumer>& bq); + GrallocConsumer(Allocation *, const sp<IGraphicBufferConsumer>& bq, int flags); virtual ~GrallocConsumer(); status_t lockNextBuffer(); diff --git a/scriptc/rs_allocation.rsh b/scriptc/rs_allocation.rsh index 6f3f8d99..03bd1ca9 100644 --- a/scriptc/rs_allocation.rsh +++ b/scriptc/rs_allocation.rsh @@ -374,8 +374,7 @@ extern const uchar __attribute__((overloadable)) #endif // (defined(RS_VERSION) && (RS_VERSION >= 18)) - -#if (defined(RS_VERSION) && (RS_VERSION >= 999)) +#if (defined(RS_VERSION) && (RS_VERSION >= 22)) #define VOP(T) \ extern T __attribute__((overloadable)) \ @@ -424,7 +423,7 @@ VOP(double4) #undef VOP -#endif //(defined(RS_VERSION) && (RS_VERSION >= 999)) +#endif //(defined(RS_VERSION) && (RS_VERSION >= 22)) #endif |
