Merge "Threading RS ForEach."
This commit is contained in:
@@ -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;
|
||||
|
||||
Binary file not shown.
@@ -3,6 +3,8 @@
|
||||
#define MAX_RADIUS 25
|
||||
|
||||
typedef struct {
|
||||
rs_allocation ain;
|
||||
|
||||
float *gaussian; //[MAX_RADIUS * 2 + 1];
|
||||
rs_matrix3x3 colorMat;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <cutils/properties.h>
|
||||
|
||||
@@ -355,6 +356,49 @@ void * Context::threadProc(void *vrsc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * Context::helperThreadProc(void *vrsc)
|
||||
{
|
||||
Context *rsc = static_cast<Context *>(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) {
|
||||
|
||||
@@ -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<Script> mRootScript;
|
||||
ObjectBaseRef<ProgramFragment> mFragment;
|
||||
ObjectBaseRef<ProgramVertex> mVertex;
|
||||
@@ -248,6 +265,7 @@ private:
|
||||
uint32_t runRootScript();
|
||||
|
||||
static void * threadProc(void *);
|
||||
static void * helperThreadProc(void *);
|
||||
|
||||
ANativeWindow *mWndSurface;
|
||||
|
||||
|
||||
@@ -137,72 +137,155 @@ uint32_t ScriptC::run(Context *rsc)
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
Context *rsc;
|
||||
ScriptC *script;
|
||||
const Allocation * ain;
|
||||
Allocation * aout;
|
||||
const void * usr;
|
||||
|
||||
uint32_t mSliceSize;
|
||||
volatile int mSliceNum;
|
||||
|
||||
const uint8_t *ptrIn;
|
||||
uint32_t eStrideIn;
|
||||
uint8_t *ptrOut;
|
||||
uint32_t eStrideOut;
|
||||
|
||||
uint32_t xStart;
|
||||
uint32_t xEnd;
|
||||
uint32_t yStart;
|
||||
uint32_t yEnd;
|
||||
uint32_t zStart;
|
||||
uint32_t zEnd;
|
||||
uint32_t arrayStart;
|
||||
uint32_t arrayEnd;
|
||||
|
||||
uint32_t dimX;
|
||||
uint32_t dimY;
|
||||
uint32_t dimZ;
|
||||
uint32_t dimArray;
|
||||
} MTLaunchStruct;
|
||||
typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
static void wc_xy(void *usr, uint32_t idx)
|
||||
{
|
||||
MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
|
||||
LOGE("usr %p, idx %i", usr, idx);
|
||||
|
||||
while (1) {
|
||||
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
|
||||
uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
|
||||
uint32_t yEnd = yStart + mtls->mSliceSize;
|
||||
yEnd = rsMin(yEnd, mtls->yEnd);
|
||||
if (yEnd <= yStart) {
|
||||
return;
|
||||
}
|
||||
|
||||
//LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
|
||||
|
||||
for (uint32_t y = yStart; y < yEnd; y++) {
|
||||
uint32_t offset = mtls->dimX * y;
|
||||
uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
|
||||
const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
|
||||
|
||||
for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) {
|
||||
((rs_t)mtls->script->mProgram.mRoot) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0);
|
||||
xPtrIn += mtls->eStrideIn;
|
||||
xPtrOut += mtls->eStrideOut;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScriptC::runForEach(Context *rsc,
|
||||
const Allocation * ain,
|
||||
Allocation * aout,
|
||||
const void * usr,
|
||||
const RsScriptCall *sc)
|
||||
{
|
||||
uint32_t dimX = ain->getType()->getDimX();
|
||||
uint32_t dimY = ain->getType()->getDimY();
|
||||
uint32_t dimZ = ain->getType()->getDimZ();
|
||||
uint32_t dimA = 0;//ain->getType()->getDimArray();
|
||||
MTLaunchStruct mtls;
|
||||
memset(&mtls, 0, sizeof(mtls));
|
||||
|
||||
uint32_t xStart = 0;
|
||||
uint32_t xEnd = 0;
|
||||
uint32_t yStart = 0;
|
||||
uint32_t yEnd = 0;
|
||||
uint32_t zStart = 0;
|
||||
uint32_t zEnd = 0;
|
||||
uint32_t arrayStart = 0;
|
||||
uint32_t arrayEnd = 0;
|
||||
if (ain) {
|
||||
mtls.dimX = ain->getType()->getDimX();
|
||||
mtls.dimY = ain->getType()->getDimY();
|
||||
mtls.dimZ = ain->getType()->getDimZ();
|
||||
//mtls.dimArray = ain->getType()->getDimArray();
|
||||
} else if (aout) {
|
||||
mtls.dimX = aout->getType()->getDimX();
|
||||
mtls.dimY = aout->getType()->getDimY();
|
||||
mtls.dimZ = aout->getType()->getDimZ();
|
||||
//mtls.dimArray = aout->getType()->getDimArray();
|
||||
} else {
|
||||
rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sc || (sc->xEnd == 0)) {
|
||||
xStart = 0;
|
||||
xEnd = ain->getType()->getDimX();
|
||||
mtls.xEnd = mtls.dimX;
|
||||
} else {
|
||||
rsAssert(xStart < dimX);
|
||||
rsAssert(xEnd <= dimX);
|
||||
rsAssert(sc->xStart < mtls.dimX);
|
||||
rsAssert(sc->xEnd <= mtls.dimX);
|
||||
rsAssert(sc->xStart < sc->xEnd);
|
||||
xStart = rsMin(dimX, sc->xStart);
|
||||
xEnd = rsMin(dimX, sc->xEnd);
|
||||
if (xStart >= xEnd) return;
|
||||
mtls.xStart = rsMin(mtls.dimX, sc->xStart);
|
||||
mtls.xEnd = rsMin(mtls.dimX, sc->xEnd);
|
||||
if (mtls.xStart >= mtls.xEnd) return;
|
||||
}
|
||||
|
||||
if (!sc || (sc->yEnd == 0)) {
|
||||
yStart = 0;
|
||||
yEnd = ain->getType()->getDimY();
|
||||
mtls.yEnd = mtls.dimY;
|
||||
} else {
|
||||
rsAssert(yStart < dimY);
|
||||
rsAssert(yEnd <= dimY);
|
||||
rsAssert(sc->yStart < mtls.dimY);
|
||||
rsAssert(sc->yEnd <= mtls.dimY);
|
||||
rsAssert(sc->yStart < sc->yEnd);
|
||||
yStart = rsMin(dimY, sc->yStart);
|
||||
yEnd = rsMin(dimY, sc->yEnd);
|
||||
if (yStart >= yEnd) return;
|
||||
mtls.yStart = rsMin(mtls.dimY, sc->yStart);
|
||||
mtls.yEnd = rsMin(mtls.dimY, sc->yEnd);
|
||||
if (mtls.yStart >= mtls.yEnd) return;
|
||||
}
|
||||
|
||||
xEnd = rsMax((uint32_t)1, xEnd);
|
||||
yEnd = rsMax((uint32_t)1, yEnd);
|
||||
zEnd = rsMax((uint32_t)1, zEnd);
|
||||
arrayEnd = rsMax((uint32_t)1, arrayEnd);
|
||||
mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd);
|
||||
mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd);
|
||||
mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd);
|
||||
mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd);
|
||||
|
||||
rsAssert(ain->getType()->getDimZ() == 0);
|
||||
|
||||
setupScript(rsc);
|
||||
Script * oldTLS = setTLS(this);
|
||||
|
||||
typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
const uint8_t *ptrIn = (const uint8_t *)ain->getPtr();
|
||||
uint32_t eStrideIn = ain->getType()->getElementSizeBytes();
|
||||
mtls.rsc = rsc;
|
||||
mtls.ain = ain;
|
||||
mtls.aout = aout;
|
||||
mtls.script = this;
|
||||
mtls.usr = usr;
|
||||
mtls.mSliceSize = 10;
|
||||
mtls.mSliceNum = 0;
|
||||
|
||||
uint8_t *ptrOut = NULL;
|
||||
uint32_t eStrideOut = 0;
|
||||
if (aout) {
|
||||
ptrOut = (uint8_t *)aout->getPtr();
|
||||
eStrideOut = aout->getType()->getElementSizeBytes();
|
||||
mtls.ptrIn = NULL;
|
||||
mtls.eStrideIn = 0;
|
||||
if (ain) {
|
||||
mtls.ptrIn = (const uint8_t *)ain->getPtr();
|
||||
mtls.eStrideIn = ain->getType()->getElementSizeBytes();
|
||||
}
|
||||
|
||||
mtls.ptrOut = NULL;
|
||||
mtls.eStrideOut = 0;
|
||||
if (aout) {
|
||||
mtls.ptrOut = (uint8_t *)aout->getPtr();
|
||||
mtls.eStrideOut = aout->getType()->getElementSizeBytes();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
LOGE("launch 1");
|
||||
rsc->launchThreads(wc_xy, &mtls);
|
||||
LOGE("launch 2");
|
||||
}
|
||||
|
||||
/*
|
||||
for (uint32_t ar = arrayStart; ar < arrayEnd; ar++) {
|
||||
for (uint32_t z = zStart; z < zEnd; z++) {
|
||||
for (uint32_t y = yStart; y < yEnd; y++) {
|
||||
@@ -221,7 +304,7 @@ void ScriptC::runForEach(Context *rsc,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
setTLS(oldTLS);
|
||||
}
|
||||
|
||||
|
||||
@@ -329,6 +329,29 @@ static uint32_t SC_allocGetDimFaces(RsAllocation va)
|
||||
return a->getType()->getDimFaces();
|
||||
}
|
||||
|
||||
const void * SC_getElementAtX(RsAllocation va, uint32_t x)
|
||||
{
|
||||
const Allocation *a = static_cast<const Allocation *>(va);
|
||||
const Type *t = a->getType();
|
||||
const uint8_t *p = (const uint8_t *)a->getPtr();
|
||||
return &p[t->getElementSizeBytes() * x];
|
||||
}
|
||||
|
||||
const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y)
|
||||
{
|
||||
const Allocation *a = static_cast<const Allocation *>(va);
|
||||
const Type *t = a->getType();
|
||||
const uint8_t *p = (const uint8_t *)a->getPtr();
|
||||
return &p[t->getElementSizeBytes() * (x + y*t->getDimX())];
|
||||
}
|
||||
|
||||
const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z)
|
||||
{
|
||||
const Allocation *a = static_cast<const Allocation *>(va);
|
||||
const Type *t = a->getType();
|
||||
const uint8_t *p = (const uint8_t *)a->getPtr();
|
||||
return &p[t->getElementSizeBytes() * (x + y*t->getDimX())];
|
||||
}
|
||||
|
||||
|
||||
static void SC_debugF(const char *s, float f) {
|
||||
@@ -350,6 +373,10 @@ static void SC_debugI32(const char *s, int32_t i) {
|
||||
LOGE("%s %i 0x%x", s, i, i);
|
||||
}
|
||||
|
||||
static void SC_debugP(const char *s, const void *p) {
|
||||
LOGE("%s %p", s, p);
|
||||
}
|
||||
|
||||
static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
|
||||
{
|
||||
GET_TLS();
|
||||
@@ -433,12 +460,18 @@ static ScriptCState::SymbolTable_t gSyms[] = {
|
||||
{ "rsAllocationGetDimFaces", (void *)&SC_allocGetDimFaces },
|
||||
{ "rsGetAllocation", (void *)&SC_getAllocation },
|
||||
|
||||
{ "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX },
|
||||
{ "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY },
|
||||
{ "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ },
|
||||
|
||||
|
||||
// Debug
|
||||
{ "_Z7rsDebugPKcf", (void *)&SC_debugF },
|
||||
{ "_Z7rsDebugPKcDv2_f", (void *)&SC_debugFv2 },
|
||||
{ "_Z7rsDebugPKcDv3_f", (void *)&SC_debugFv3 },
|
||||
{ "_Z7rsDebugPKcDv4_f", (void *)&SC_debugFv4 },
|
||||
{ "_Z7rsDebugPKci", (void *)&SC_debugI32 },
|
||||
{ "_Z7rsDebugPKcPKv", (void *)&SC_debugP },
|
||||
//extern void __attribute__((overloadable))rsDebug(const char *, const void *);
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <cutils/atomic.h>
|
||||
|
||||
#ifndef ANDROID_RS_BUILD_FOR_HOST
|
||||
#include <EGL/egl.h>
|
||||
|
||||
@@ -14,6 +14,12 @@ extern uint32_t rsAllocationGetDimZ(rs_allocation);
|
||||
extern uint32_t rsAllocationGetDimLOD(rs_allocation);
|
||||
extern uint32_t rsAllocationGetDimFaces(rs_allocation);
|
||||
|
||||
extern const void * __attribute__((overloadable))
|
||||
rsGetElementAt(rs_allocation, uint32_t x);
|
||||
extern const void * __attribute__((overloadable))
|
||||
rsGetElementAt(rs_allocation, uint32_t x, uint32_t y);
|
||||
extern const void * __attribute__((overloadable))
|
||||
rsGetElementAt(rs_allocation, uint32_t x, uint32_t y, uint32_t z);
|
||||
|
||||
|
||||
// Debugging
|
||||
|
||||
Reference in New Issue
Block a user