diff --git a/libs/rs/java/ImageProcessing/res/raw/horizontal_blur.rs b/libs/rs/java/ImageProcessing/res/raw/horizontal_blur.rs index 7b0e6bcc68fbb..10815fb33075d 100644 --- a/libs/rs/java/ImageProcessing/res/raw/horizontal_blur.rs +++ b/libs/rs/java/ImageProcessing/res/raw/horizontal_blur.rs @@ -5,17 +5,14 @@ #include "ip.rsh" -uchar4 * ScratchPixel; - -#pragma rs export_var(ScratchPixel) - void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { uchar4 *output = (uchar4 *)v_out; - const uchar4 *input = (uchar4 *)v_in; const FilterStruct *fs = (const FilterStruct *)usrData; + const uchar4 *input = (const uchar4 *)rsGetElementAt(fs->ain, 0, y); float4 blurredPixel = 0; float4 currentPixel = 0; + for(int r = -fs->radius; r <= fs->radius; r ++) { // Stepping left and right away from the pixel int validW = x + r; diff --git a/libs/rs/java/ImageProcessing/res/raw/horizontal_blur_bc.bc b/libs/rs/java/ImageProcessing/res/raw/horizontal_blur_bc.bc index c9ba5d9c5cec2..5920f3ab0d47e 100644 Binary files a/libs/rs/java/ImageProcessing/res/raw/horizontal_blur_bc.bc and b/libs/rs/java/ImageProcessing/res/raw/horizontal_blur_bc.bc differ diff --git a/libs/rs/java/ImageProcessing/res/raw/ip.rsh b/libs/rs/java/ImageProcessing/res/raw/ip.rsh index 4073304f6490f..dea92c3568d2f 100644 --- a/libs/rs/java/ImageProcessing/res/raw/ip.rsh +++ b/libs/rs/java/ImageProcessing/res/raw/ip.rsh @@ -3,6 +3,8 @@ #define MAX_RADIUS 25 typedef struct { + rs_allocation ain; + float *gaussian; //[MAX_RADIUS * 2 + 1]; rs_matrix3x3 colorMat; diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs index ecbfac4631e61..aa6b6fa8a179c 100644 --- a/libs/rs/java/ImageProcessing/res/raw/threshold.rs +++ b/libs/rs/java/ImageProcessing/res/raw/threshold.rs @@ -24,7 +24,6 @@ float saturation; static float inWMinInB; static float outWMinOutB; static float overInWMinInB; -static FilterStruct filterStruct; #pragma rs export_var(height, width, radius, InPixel, OutPixel, ScratchPixel, inBlack, outBlack, inWhite, outWhite, gamma, saturation, InPixel, OutPixel, ScratchPixel, vBlurScript, hBlurScript) #pragma rs export_func(filter, filterBenchmark); @@ -106,138 +105,70 @@ static void computeGaussianWeights() { } } -// This needs to be inline -static float4 levelsSaturation(float4 currentPixel) { - float3 temp = rsMatrixMultiply(&colorMat, currentPixel.xyz); - temp = (clamp(temp, 0.1f, 255.f) - inBlack) * overInWMinInB; - temp = pow(temp, (float3)gamma); - currentPixel.xyz = clamp(temp * outWMinOutB + outBlack, 0.1f, 255.f); - return currentPixel; -} - static void processNoBlur() { - int w, h, r; - int count = 0; - float inWMinInB = inWhite - inBlack; float outWMinOutB = outWhite - outBlack; float4 currentPixel = 0; - for(h = 0; h < height; h ++) { - for(w = 0; w < width; w ++) { - uchar4 *input = InPixel + h*width + w; + for(int h = 0; h < height; h ++) { + uchar4 *input = InPixel + h*width; + uchar4 *output = OutPixel + h*width; + for(int w = 0; w < width; w ++) { //currentPixel.xyz = convert_float3(input.xyz); currentPixel.x = (float)(input->x); currentPixel.y = (float)(input->y); currentPixel.z = (float)(input->z); - currentPixel = levelsSaturation(currentPixel); + float3 temp = rsMatrixMultiply(&colorMat, currentPixel.xyz); + temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB; + temp = pow(temp, (float3)gamma); + currentPixel.xyz = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f); - uchar4 *output = OutPixel + h*width + w; //output.xyz = convert_uchar3(currentPixel.xyz); output->x = (uint8_t)currentPixel.x; output->y = (uint8_t)currentPixel.y; output->z = (uint8_t)currentPixel.z; output->w = input->w; - } - } - rsSendToClient(&count, 1, 4, 0); -} -static void horizontalBlurLevels() { - float4 blurredPixel = 0; - float4 currentPixel = 0; - // Horizontal blur - int w, h, r; - for(h = 0; h < height; h ++) { - uchar4 *output = OutPixel + h*width; - - for(w = 0; w < width; w ++) { - blurredPixel = 0; - - for(r = -radius; r <= radius; r ++) { - // Stepping left and right away from the pixel - int validW = w + r; - // Clamp to zero and width max() isn't exposed for ints yet - if(validW < 0) { - validW = 0; - } - if(validW > width - 1) { - validW = width - 1; - } - //int validW = rsClamp(w + r, 0, width - 1); - - uchar4 *input = InPixel + h*width + validW; - - float weight = gaussian[r + radius]; - currentPixel.x = (float)(input->x); - currentPixel.y = (float)(input->y); - currentPixel.z = (float)(input->z); - //currentPixel.w = (float)(input->a); - - blurredPixel.xyz += currentPixel.xyz * weight; - } - - blurredPixel = levelsSaturation(blurredPixel); - - output->x = (uint8_t)blurredPixel.x; - output->y = (uint8_t)blurredPixel.y; - output->z = (uint8_t)blurredPixel.z; - //output->a = (uint8_t)blurredPixel.w; + input++; output++; } } } -static void initStructs() { - filterStruct.gaussian = gaussian; - filterStruct.width = width; - filterStruct.height = height; - filterStruct.radius = radius; +static void blur() { + computeGaussianWeights(); + + FilterStruct fs; + fs.gaussian = gaussian; + fs.width = width; + fs.height = height; + fs.radius = radius; + + fs.ain = rsGetAllocation(InPixel); + rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel), &fs); + + fs.ain = rsGetAllocation(ScratchPixel); + rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs); } void filter() { - RS_DEBUG(height); - RS_DEBUG(width); RS_DEBUG(radius); - initStructs(); - computeColorMatrix(); - if(radius == 0) { - processNoBlur(); - return; + if(radius > 0) { + blur(); } - - computeGaussianWeights(); - - horizontalBlurLevels(); - - rsForEach(vBlurScript, - rsGetAllocation(InPixel), - rsGetAllocation(OutPixel), - &filterStruct); + processNoBlur(); int count = 0; rsSendToClient(&count, 1, 4, 0); } void filterBenchmark() { - initStructs(); - - computeGaussianWeights(); - - rsForEach(hBlurScript, - rsGetAllocation(InPixel), - rsGetAllocation(OutPixel), - &filterStruct); - - rsForEach(vBlurScript, - rsGetAllocation(InPixel), - rsGetAllocation(OutPixel), - &filterStruct); + blur(); int count = 0; rsSendToClient(&count, 1, 4, 0); diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold_bc.bc b/libs/rs/java/ImageProcessing/res/raw/threshold_bc.bc index 8f37fdc349ccb..2b5d2543c38d3 100644 Binary files a/libs/rs/java/ImageProcessing/res/raw/threshold_bc.bc and b/libs/rs/java/ImageProcessing/res/raw/threshold_bc.bc differ diff --git a/libs/rs/java/ImageProcessing/res/raw/vertical_blur.rs b/libs/rs/java/ImageProcessing/res/raw/vertical_blur.rs index 846f515a4eb09..f5f2d69b12a46 100644 --- a/libs/rs/java/ImageProcessing/res/raw/vertical_blur.rs +++ b/libs/rs/java/ImageProcessing/res/raw/vertical_blur.rs @@ -5,14 +5,10 @@ #include "ip.rsh" -uchar4 * ScratchPixel; - -#pragma rs export_var(ScratchPixel) - void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { uchar4 *output = (uchar4 *)v_out; - const uchar4 *input = (uchar4 *)v_in; const FilterStruct *fs = (const FilterStruct *)usrData; + const uchar4 *input = (const uchar4 *)rsGetElementAt(fs->ain, x, 0); float4 blurredPixel = 0; float4 currentPixel = 0; @@ -27,19 +23,21 @@ void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32 validH = fs->height - 1; } - uchar4 *input = ScratchPixel + validH * fs->width + x; + const uchar4 *i = input + validH * fs->width; + //const uchar4 *i = (const uchar4 *)rsGetElementAt(fs->ain, x, validH); float weight = fs->gaussian[r + fs->radius]; - currentPixel.x = (float)(input->x); - currentPixel.y = (float)(input->y); - currentPixel.z = (float)(input->z); + currentPixel.x = (float)(i->x); + currentPixel.y = (float)(i->y); + currentPixel.z = (float)(i->z); blurredPixel.xyz += currentPixel.xyz * weight; #else int validH = rsClamp(y + r, 0, height - 1); - uchar4 *input = ScratchPixel + validH * width + x; - blurredPixel.xyz += convert_float3(input->xyz) * gaussian[r + fs->radius]; + validH -= y; + uchar4 *i = input + validH * width + x; + blurredPixel.xyz += convert_float3(i->xyz) * gaussian[r + fs->radius]; #endif } diff --git a/libs/rs/java/ImageProcessing/res/raw/vertical_blur_bc.bc b/libs/rs/java/ImageProcessing/res/raw/vertical_blur_bc.bc index af1cd8e097772..be5d0e4ee69b2 100644 Binary files a/libs/rs/java/ImageProcessing/res/raw/vertical_blur_bc.bc and b/libs/rs/java/ImageProcessing/res/raw/vertical_blur_bc.bc differ diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java index 21c3d7450096c..0ed1185916e49 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -376,10 +376,7 @@ public class ImageProcessingActivity extends Activity mScratchPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapScratch); mScriptVBlur = new ScriptC_Vertical_blur(mRS, getResources(), R.raw.vertical_blur_bc, false); - mScriptVBlur.bind_ScratchPixel(mScratchPixelsAllocation); - mScriptHBlur = new ScriptC_Horizontal_blur(mRS, getResources(), R.raw.horizontal_blur_bc, false); - mScriptHBlur.bind_ScratchPixel(mScratchPixelsAllocation); mScript = new ScriptC_Threshold(mRS, getResources(), R.raw.threshold_bc, false); mScript.set_width(mBitmapIn.getWidth()); @@ -431,8 +428,8 @@ public class ImageProcessingActivity extends Activity android.util.Log.v("Img", "Renderscript frame time core ms " + t); long javaTime = javaFilter(); - mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms"); + //mBenchmarkResult.setText("RS: " + t + " ms"); mRadius = oldRadius; mScript.set_radius(mRadius); diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Horizontal_blur.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Horizontal_blur.java index 8ee50a833aebd..c447b9b6b97b1 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Horizontal_blur.java +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Horizontal_blur.java @@ -26,17 +26,5 @@ public class ScriptC_Horizontal_blur extends ScriptC { super(rs, resources, id, isRoot); } - private final static int mExportVarIdx_ScratchPixel = 0; - private Allocation mExportVar_ScratchPixel; - public void bind_ScratchPixel(Allocation v) { - mExportVar_ScratchPixel = v; - if(v == null) bindAllocation(null, mExportVarIdx_ScratchPixel); - else bindAllocation(v, mExportVarIdx_ScratchPixel); - } - - public Allocation get_ScratchPixel() { - return mExportVar_ScratchPixel; - } - } diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Vertical_blur.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Vertical_blur.java index 0215f6067c96d..cee74d965b771 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Vertical_blur.java +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ScriptC_Vertical_blur.java @@ -26,17 +26,5 @@ public class ScriptC_Vertical_blur extends ScriptC { super(rs, resources, id, isRoot); } - private final static int mExportVarIdx_ScratchPixel = 0; - private Allocation mExportVar_ScratchPixel; - public void bind_ScratchPixel(Allocation v) { - mExportVar_ScratchPixel = v; - if(v == null) bindAllocation(null, mExportVarIdx_ScratchPixel); - else bindAllocation(v, mExportVarIdx_ScratchPixel); - } - - public Allocation get_ScratchPixel() { - return mExportVar_ScratchPixel; - } - } diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 68eca4495acd9..629b481142893 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -23,6 +23,7 @@ #include #include +#include #include @@ -355,6 +356,49 @@ void * Context::threadProc(void *vrsc) return NULL; } +void * Context::helperThreadProc(void *vrsc) +{ + Context *rsc = static_cast(vrsc); + uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount); + + LOGE("helperThreadProc 1 %p idx=%i", rsc, idx); + + rsc->mWorkers.mLaunchSignals[idx].init(); + rsc->mWorkers.mNativeThreadId[idx] = gettid(); + + //cpu_set_t cpset[16]; + //int ret = sched_getaffinity(rsc->mWorkers.mNativeThreadId[idx], sizeof(cpset), &cpset); + //LOGE("ret = %i", ret); + +//sched_setaffinity + + setpriority(PRIO_PROCESS, rsc->mWorkers.mNativeThreadId[idx], rsc->mThreadPriority); + while(rsc->mRunning) { + rsc->mWorkers.mLaunchSignals[idx].wait(); + if (rsc->mWorkers.mLaunchCallback) { + LOGE("helperThreadProc 4"); + rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx); + } + LOGE("helperThreadProc 5"); + android_atomic_dec(&rsc->mWorkers.mRunningCount); + rsc->mWorkers.mCompleteSignal.set(); + } + return NULL; +} + +void Context::launchThreads(WorkerCallback_t cbk, void *data) +{ + mWorkers.mLaunchData = data; + mWorkers.mLaunchCallback = cbk; + mWorkers.mRunningCount = (int)mWorkers.mCount; + for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) { + mWorkers.mLaunchSignals[ct].set(); + } + while(mWorkers.mRunningCount) { + mWorkers.mCompleteSignal.wait(); + } +} + void Context::setPriority(int32_t p) { // Note: If we put this in the proper "background" policy @@ -371,7 +415,10 @@ void Context::setPriority(int32_t p) // success; reset the priority as well } #else - setpriority(PRIO_PROCESS, mNativeThreadId, p); + setpriority(PRIO_PROCESS, mNativeThreadId, p); + for (uint32_t ct=0; ct < mWorkers.mCount; ct++) { + setpriority(PRIO_PROCESS, mWorkers.mNativeThreadId[ct], p); + } #endif } @@ -421,10 +468,26 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth) timerInit(); timerSet(RS_TIMER_INTERNAL); - LOGV("RS Launching thread"); + LOGV("RS Launching thread(s)"); + mWorkers.mCount = 2; + mWorkers.mThreadId = (pthread_t *) calloc(mWorkers.mCount, sizeof(pthread_t)); + mWorkers.mNativeThreadId = (pid_t *) calloc(mWorkers.mCount, sizeof(pid_t)); + mWorkers.mLaunchSignals = new Signal[mWorkers.mCount]; + mWorkers.mLaunchCallback = NULL; status = pthread_create(&mThreadId, &threadAttr, threadProc, this); if (status) { LOGE("Failed to start rs context thread."); + return; + } + mWorkers.mRunningCount = 0; + mWorkers.mLaunchCount = 0; + for (uint32_t ct=0; ct < mWorkers.mCount; ct++) { + status = pthread_create(&mWorkers.mThreadId[ct], &threadAttr, helperThreadProc, this); + if (status) { + mWorkers.mCount = ct; + LOGE("Created fewer than expected number of RS threads."); + break; + } } while(!mRunning) { diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 06433a17f1491..98ad3a4e90421 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -65,6 +65,7 @@ public: Script * mScript; }; + typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); //StructuredAllocationContext mStateAllocation; ElementState mStateElement; @@ -172,6 +173,8 @@ public: bool ext_OES_texture_npot() const {return mGL.OES_texture_npot;} + void launchThreads(WorkerCallback_t cbk, void *data); + protected: Device *mDev; @@ -222,6 +225,20 @@ protected: pthread_t mThreadId; pid_t mNativeThreadId; + struct Workers { + volatile int mRunningCount; + volatile int mLaunchCount; + uint32_t mCount; + pthread_t *mThreadId; + pid_t *mNativeThreadId; + Signal mCompleteSignal; + + Signal *mLaunchSignals; + WorkerCallback_t mLaunchCallback; + void *mLaunchData; + }; + Workers mWorkers; + ObjectBaseRef