I'm building an Android app using RenderScript. I want to create a 2D array that contains a sum of all the ints in the rectangle from the origin up till (x, y).
As stated here, RenderScript is a C99-derived language. Any function with the RS_KERNEL
keyword will be called once for every pixel by the framework. No guarantees are made in which order this will be called. From Java/Kotlin generateGridPixelCount
is called by providing it a piece of allocated memory. Every item is set by the returned value accordingly.
So, for example:
Input Output
-----------------
| 0 | 0 | 0 | 0 |
------------- -----------------
| 1 | 1 | 1 | | 0 | 1 | 2 | 3 |
------------- -----------------
| 0 | 1 | 1 | | 0 | 1 | 3 | 5 |
------------- -----------------
| 1 | 1 | 1 | | 0 | 2 | 5 | 8 |
------------- -----------------
For small arrays this is doable, but when the array is as big as the screen (1080x2280), the function I've written takes ages.
static bool shouldCheckPixel(uint x, uint y) {
return (x + y) % (width / stepSize) == 0 || (x - y) % (width / stepSize) == 0;
}
int RS_KERNEL generateGridPixelCount(uint x, uint y) {
int pixelCount = 0;
for (int dx = 0; dx < x; dx++) {
for (int dy = 0; dy < y; dy++) {
if (shouldCheckPixel(dx, dy)) {
pixelCount++;
}
}
}
return pixelCount;
}
However, if pixelCount++;
is removed or the if statement is removed, it finishes almost instantly. It's when it's combined when it gets slow.
Previous RS_KERNEL
function loop over the output. This can be reversed:
void RS_KERNEL generateGridPixelCount(uchar4 input, uint x, uint y) {
if (shouldCheckPixel(x, y)) {
for (int x = 0; x < dx; x++) {
for (int y = 0; y < dy; y++) {
rsAtomicInc(*pixelArray[x][y]);
}
}
}
}
What's the best way to calculate this array?