0

How can I know current index in an allocation inside the root() function?

For now I'm doing it by binding an extra pointer - start of the allocation. Something like this:

// Java code
Allocation in = Allocation.create...;
mScript.bind_gStart(in);

and then use some pointer arithmetic in the renderscript:

// RS file - assuming 1D array
void root(const uint8_t *in) {
  size_t idx = in - gStart;
  ...
}

Is this guaranteed to work? Are there any better / more straightforward ways of doing this? Somehow, I feel like there must be some curIdx pseudo-variable, or something.

rincewind
  • 1,103
  • 8
  • 29

1 Answers1

1

A common root() function prototype is:

void root(const uchar4 *data_in, uchar4 *data_out, const void * usrData, uint32_t x, uint32_t y)

The x and y parameters designate indices within the input allocation. I've used them succefully for image processing, such as in this:

void root(const uchar *data_in, uchar4 *data_out, const void * usrData, uint32_t x, uint32_t y) {
int sum_x;
int sum_y;
unsigned char channel;
int color;

width = rsAllocationGetDimX(gIn);
height = rsAllocationGetDimY(gOut);

if ( (x > 1) & (y > 1) & (x < width-1) & (y < height-1)) {
    sum_x = 0;
    sum_x += -1 * gPixels[(y-1)*width+x-1];
    sum_x +=  1 * gPixels[(y-1)*width+x+1];
    sum_x += -2 * gPixels[y*width+x-1];
    sum_x +=  2 * gPixels[y*width+x+1];
    sum_x += -1 * gPixels[(y+1)*width+x-1];
    sum_x +=  1 * gPixels[(y+1)*width+x+1];

    sum_y = 0;
    sum_y += -1 * gPixels[(y-1)*width+x-1];
    sum_y += -2 * gPixels[(y-1)*width+x];
    sum_y += -1 * gPixels[(y-1)*width+x+1];
    sum_y +=  1 * gPixels[(y+1)*width+x-1];
    sum_y +=  2 * gPixels[(y+1)*width+x];
    sum_y +=  1 * gPixels[(y+1)*width+x+1];

    //channel = (byte) (Math.hypot(sum_x,  sum_y)); // L2 norm
    channel = (uchar) (abs(sum_x) + abs(sum_y)); // L1 norm
    //color = 0xFF000000 | (channel << 16) | (channel << 8) | channel;
    data_out->w = 0xFF;
    data_out->x = channel;
    data_out->y = channel;
    data_out->z = channel;
}
else {
    data_out->w = 0xFF;
    data_out->x = 0xFF;
    data_out->y = 0xFF;
    data_out->z = 0xFF;
}

}

  • Thanks, it worked. However, it would be useful to have somewhere to read about all possible overloads of the root() function. I did some experimenting, and the logic of how this function accepts indices looks rather whimsical. Apparently, argument names also matter! Say, if I make the function take both x and y and pass a 1D array, all works as expected. If I take just x, the same thing. However, if I rename x into y, the function gets called only once (for 1D case). If, on the other hand, I rename the parameter as "q", it considers it as x. Weird. – rincewind Jul 13 '12 at 20:01
  • 1
    From slang source code, it seems the below root() prototypes are accepted (ICS): (In, Out, UsrData, X, Y), (In, Out, UsrData, X), (In, Out, UsrData), (In, Out), and finally (In). It seems like it does expects "x" and "y" and nothing else ... Take a look at Android source code: /frameworks/compile/slang/slang_rs_export_foreach.cpp. – chakishante Jul 16 '12 at 10:00