简体   繁体   中英

How to make Renderscript update a pointer to struct?

So I have this struct with a pointer in Renderscript code:

typedef struct __attribute__((packed, aligned(4))) RGB {
    float red;
    float green;
    float blue;
} RGB_t;

RGB_t *rgb;

This is how I'm allocating and binding memory to this pointer:

ScriptField_RGB rgbs = new ScriptField_RGB(mRS, bitmap.getWidth()*bitmap.getHeight());
function_script.bind_rgb(rgbs);

This is how I set my initial values:

int index = 0;
for(int y = 0; y < bitmap.getHeight(); ++y) {
    for(int x = 0; x < bitmap.getWidth(); ++x) {
       int color = bitmap.getPixel(x, y);
       ScriptField_RGB.Item i = new ScriptField_RGB.Item();
       i.red = Color.red(color) / 255.0f;
       i.green = Color.green(color) / 255.0f;
       i.blue = Color.blue(color) / 255.0f;
       rgbs.set(i, index, false);
       index++;
   }
}

rgbs.copyAll();

'function_script' is a script with a kernel to populate 'RGB_t*', it's exactly like that:

#pragma version(1)
#pragma rs java_package_name(my.package)

#include "rgb.rs"

void __attribute__((kernel)) root(RGB_t pixel, uint32_t x) {
    //rsDebug("before", rgb[x].red,rgb[x].green,rgb[x].blue);
    rgb[x].red = pixel.red * 255.0f;
    rgb[x].green = pixel.green * 255.0f;
    rgb[x].blue = pixel.blue * 255.0f;
    //rsDebug("after", rgb[x].red,rgb[x].green,rgb[x].blue);
}

Running this kernel with:

function_script.forEach_root(arrayOperational);

doesn't update my ScriptField values at Android Layer. I still have the old values that I've settled before.

So if I call:

rgbs.get(index)

I'll get exactly my old value, running after 'foreach root' call, of course.

How can I reflect my changes in the Android Layer?

Since you're dealing with Bitmap like data (RGB values), you should consider using input and output Allocation objects rather than your own bindings. Rendescript will efficiently handle that for you rather than having to manually bind fields like this.

However, if you must do this binding, you'll need to setup the usage of the field to include Allocation.USAGE_SHARED (use a different, overloaded constructor.) With that in place, you should be able to call updateAllocation() on the field object in Java to get the latest data from the script. If that doesn't work (it depends on the auto-generated code), you could try calling getAllocation() then calling Allocation.syncAll(Allocation.USAGE_SHARED) to get the Allocation updated with any changes from the script. At that point your field access methods should give the updated values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM