【问题标题】:Renderscript, forEach_root, and porting from OpenCLRenderscript、forEach_root 和从 OpenCL 移植
【发布时间】:2013-05-06 05:51:43
【问题描述】:

1) 如何在 forEach_root() 中访问除当前元素之外的其他元素?

在 OpenCL 中,我们有指向第一个元素的指针,然后可以使用 get_global_id(0) 来获取当前索引。但是我们仍然可以访问所有其他元素。在 Renderscript 中,我们只有指向当前元素的指针吗?

2) 如何在 forEach_root() 中循环分配分配?

我有一个在 java 中使用嵌套(双)循环的代码。 Renderscript 自动执行外循环,但我找不到任何有关实现内循环的信息。以下是我的最大努力:

void root(const float3 *v_in, float3 *v_out) {
  rs_allocation alloc = rsGetAllocation(v_in);
  uint32_t cnt = rsAllocationGetDimX(alloc);
  *v_out = 0;
  for(int i=0; i<cnt; i++)  
    *v_out += v_in[i];
}

但是这里 rsGetAllocation() 在从 forEach_root() 调用时失败。

05-11 21:31:29.639: E/RenderScript(17032): ScriptC::ptrToAllocation, failed to find 0x5beb1a40

以防我添加在 Windows 下运行良好的 OpenCL 代码。我正在尝试将其移植到 Renderscript

typedef float4 wType;

__kernel void gravity_kernel(__global wType *src,__global wType *dst)
{
  int id = get_global_id(0);
  int count = get_global_size(0);
  double4 tmp = 0;
  for(int i=0;i<count;i++) {
    float4 diff = src[i] - src[id];
    float sq_dist = dot(diff, diff);
    float4 norm = normalize(diff);
    if (sq_dist<0.5/60)
      tmp += convert_double4(norm*sq_dist);
    else
      tmp += convert_double4(norm/sq_dist);
  }
  dst[id] = convert_float4(tmp);
}

【问题讨论】:

    标签: renderscript


    【解决方案1】:

    您可以在根函数之外提供数据。在当前的 android 版本 (4.2) 中,您可以执行以下操作(这是来自图像处理场景的示例):

    渲染脚本 sn-p:

    #pragma version(1)
    #pragma rs java_package_name(com.example.renderscripttests)
    
    //Define global variables in your renderscript:
    rs_allocation pixels;
    int width;
    int height;
    
    // And access these in your root function via rsGetElementAt(pixels, px, py)
    void root(uchar4 *v_out, uint32_t x, uint32_t y)
    {
        for(int px = 0; px < width; ++px)
            for(int py = 0; py < height; ++py)
            {
                // unpack a color to a float4
                float4 f4 = rsUnpackColor8888(*(uchar*)rsGetElementAt(pixels, px, py));
                ...
    

    Java 文件 sn-p

    // In your java file, create a renderscript:
    RenderScript renderscript = RenderScript.create(this);
    
    ScriptC_myscript script = new ScriptC_myscript(renderscript);
    
    // Create Allocations for in- and output (As input the bitmap 'bitmapIn' should be used):
    Allocation pixelsIn = Allocation.createFromBitmap(renderscript, bitmapIn,
             Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
    Allocation pixelsOut = Allocation.createTyped(renderscript, pixelsIn.getType());
    
    // Set width, height and pixels in the script:
    script.set_width(640);
    script.set_height(480);
    script.set_pixels(pixelsIn);
    
    // Call the for each loop:
    script.forEach_root(pixelsOut);
    
    // Copy Allocation to the bitmap 'bitmapOut':
    pixelsOut.copyTo(bitmapOut);
    

    您可以看到,在调用 forEach_root 函数计算“pixelsOut”的值时,输入“pixelsIn”之前已设置并在渲染脚本中使用。宽度和高度也是预先设置的。

    【讨论】:

    • 谢谢!但是假设您的示例中有 2 个线程,它们会做同样的工作吗?两个线程都会循环通过相同的像素?另一个问题:在您的示例中,x & y 是否声明了两次?
    • 我还没试过java端的两个线程是否会使用同一个脚本发生冲突。在'new ScriptC_myscript(renderscript);'的情况下在渲染脚本端创建不同的对象,我认为它应该可以工作。我将两个循环中的 x 和 y 编辑为 px 和 py。 (x和y指的是'v_out'的'位置'
    • 我明白了,你的意思是“幕后”的线程。在 java 端的“pixelsOut”中的每个元素都会调用 renderscript 的 root() - 这项工作可能由多个线程同时完成。这样的元素由渲染脚本端的“v_out”表示。在示例中,您可以计算位置“x”和“y”处的每个元素“v_out”——这是自动提供的——但访问整个 rs_allocation 'pixels',如两个 for 循环中所示。
    • 详尽的解释!
    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 2011-12-22
    • 2010-10-09
    相关资源
    最近更新 更多