传递数组到rsForEach在Renderscript计算 [英] Passing Array to rsForEach in Renderscript Compute

查看:495
本文介绍了传递数组到rsForEach在Renderscript计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现有一个在RenderScript缺乏好的文档,为我所知道的,的forEach 的RS是执行根()在分配每个单项。

I found there's lacking good documentation in RenderScript, for what I know, forEach in RS is to execute the root() for each individual item in the allocation.

我试图做一个库Renderscript,做图像处理,作为一个起点,我达到了这个<一href="http://stackoverflow.com/questions/10090583/how-to-write-a-convolution-multiplication-in-android-renderscript">great回答。但问题是,在模糊操作上的每个的像素与每个像素都需要计算另一个循环(正与模糊宽度)。虽然在多内核上运行,它仍然是一个有点太慢了。

I am trying to make a library for Renderscript that does Image processing, as a starting point, I reached this great answer. But the problem, is that the blur operation is on Each pixel and each pixel requires another loop (n with blur width) of calculation. Although running on multi-core, it is still a bit too slow.

我想修改它,以允许(两次通过)箱式滤波器,但是这需要工作的一个单行或单列代替细胞。那么,有没有什么办法要求的foreach发送一个数组根()?

I am trying to modify it to allow (two-pass) box filter, but that requires working on a single row or column instead of cell. So, is there any way to ask foreach to send an array to root()?

推荐答案

rsForEach只能在分配工作。

rsForEach can only operate upon Allocations.

如果你想有rsForEach函数调用根()对每个你必须传入,其尺寸是长度相同的行数,然后制定出哪一行,你应该是一个分配的图像的行在里面工作的根()(同样,对于每列运行)。 RenderScript然后应划分到上可用的资源(多个行同时对多芯的设备正在处理)。

If you want to have the rsForEach function call root() for each of the image rows you have to pass in an Allocation that is sized to be the same length as the number of rows and then work out which row you should be operating on inside root() (similarly for operating on each column). RenderScript should then divide up the work to run on the resources available (more than one row being processed at the same time on multi core devices).

你能做到这一点的方法之一是传递一个配置,让图像行的偏移量(图像数据阵列内)。根内的V_IN参数()将被行偏移。由于rsForEach调用运行时的分配不是图像数据使用V_OUT参数可以不写出来的图像,你必须单独绑定输出图像。

One way you could do that is by passing in an Allocation that give the offsets (within the image data array) of the image rows. The v_in argument inside the root() will then be the row offset. Since the Allocations the rsForEach call is operating upon is not the image data you cannot write the image out using the v_out argument and you must bind the output image separately.

下面是一些RenderScript,显示这样的:

Here is some RenderScript that show this:

#pragma version(1)
#pragma rs java_package_name(com.android.example.hellocompute)

rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;

int mImageWidth;
const uchar4 *gInPixels;
uchar4 *gOutPixels;

void init() {
}

static const int kBlurWidth = 20;

//
// This is called per row.
// The row indices are passed in as v_in or you could also use the x argument and multiply it by image width.
//
void root(const int32_t *v_in, int32_t *v_out, const void *usrData, uint32_t x, uint32_t y) {
    float3 blur[kBlurWidth];
    float3 cur_colour = {0.0f, 0.0f, 0.0f};

    for ( int i = 0; i < kBlurWidth; i++) {
        float3 init_colour = {0.0f, 0.0f, 0.0f};
        blur[i] = init_colour;
    }

    int32_t row_index = *v_in;
    int blur_index = 0;

    for ( int i = 0; i < mImageWidth; i++) {
        float4 pixel_colour = rsUnpackColor8888(gInPixels[i + row_index]);

        cur_colour -= blur[blur_index];
        blur[blur_index] = pixel_colour.rgb;
        cur_colour += blur[blur_index];

        blur_index += 1;
        if ( blur_index >= kBlurWidth) {
            blur_index = 0;
        }

        gOutPixels[i + row_index] = rsPackColorTo8888(cur_colour/(float)kBlurWidth);
        //gOutPixels[i + row_index] = rsPackColorTo8888(pixel_colour);
    }
}


void filter() {
    rsDebug("Number of rows:", rsAllocationGetDimX(gIn));
    rsForEach(gScript, gIn, gOut, NULL);
}

这将使用下面的Java进行设置:

This would be setup using the following Java:

    mBlurRowScript = new ScriptC_blur_row(mRS, getResources(), R.raw.blur_row);

    int row_width = mBitmapIn.getWidth();

    //
    // Create an allocation that indexes each row.
    //
    int num_rows = mBitmapIn.getHeight();
    int[] row_indices = new int[num_rows];
    for ( int i = 0; i < num_rows; i++) {
        row_indices[i] = i * row_width;
    }
    Allocation row_indices_alloc = Allocation.createSized( mRS, Element.I32(mRS), num_rows, Allocation.USAGE_SCRIPT);
    row_indices_alloc.copyFrom(row_indices);

    //
    // The image data has to be bound to the pointers within the RenderScript so it can be accessed
    // from the root() function.
    //
    mBlurRowScript.bind_gInPixels(mInAllocation);
    mBlurRowScript.bind_gOutPixels(mOutAllocation);

    // Pass in the image width
    mBlurRowScript.set_mImageWidth(row_width);

    //
    // Pass in the row indices Allocation as the input. It is also passed in as the output though the output is not used.
    //
    mBlurRowScript.set_gIn(row_indices_alloc);
    mBlurRowScript.set_gOut(row_indices_alloc);
    mBlurRowScript.set_gScript(mBlurRowScript);
    mBlurRowScript.invoke_filter();

这篇关于传递数组到rsForEach在Renderscript计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆