DSP

Android的Renderscript学习总结

2019-07-13 20:07发布

  1.  什么是RenderScript? Renderscript是一个提供底层与平台无关的高性能的3D图形渲染和计算操作的API(C99标准)。
  2.  优缺点:
      优点:
    A 可移植性,设计运行于多种不同的处理器CPU,GPU,DSP等。
    B 高性能的计算操作API. 
    C 易用,简化了操作。
      缺点:A 复杂度高,新的API。B 调试困难,因为多处理器支持。
  3. 系统结构:RS运行于底层并与VM通信。App同样运行于VM中,VM保留所有对RS内存的控制,VM分配的内存通过绑定让RS层可以访问,对于RS的调用都是异步的。
      A Renderscript runtime API。
        a 内存分配请求
        b 大量的重载了多个版本的关于矢量和标量类型数学函数,一些可用操作诸如加、乘、点乘和叉乘,以及原子算术和比较函数等等
        b 原始数据与向量的转换,矩阵转换,数据与时间转换的方法。
        c Renderscript支持的数据类型和结构,例如定义二维,三维或四维向量的Vector类型
        d 日志函数
      B Reflected layer(反射层)API
        反射的东西:
        a 每个.rs生成一个类,里面包括这些:
    非静态方法:不能有返回值,异步执行,想要返回值请用rsSendToClient()
    非静态全局变量:get 与 set方法,如果是const就只有set方法。
    全局指针: bind 与get
        b 每个struct结构体生成一个类.可以在java分配内存矢量化。生成这些:
      1 重载构造函数,可以指定实例个数与特定的内存空间。
            2 静态内部内item.
            3 get and set field
            4 createElement
            5 resize
            6 copyAll 
      C Android framework API
  4. 内存分配APIs:动态分配的内存才需要绑定,静态分配的内存在rs编译时自动创建
      Element类:代表malloc对于的(sizeof(int))部分,并且封装内存分配的一个单元,诸如一个单一float值或一个struct。
      Type类:封装元素和要分配的元素个数(在我们的示例中是10)。你可以认为一个Type是一个Element数组。
      Allocation类:基于给定Type执行实际内存分配并且代表实际分配的内存。

  5. 内存处理
      非静态全局变量:在rs编译时分配内存,vm可以读写,如果在rs层被初始化,会传播到VM。
      A 分配和绑定动态内存到RS
      B 读写内存
        a 读写全局变量:在rs层做的修改不会传播到framework layer,反之却不同。
        b 读写全局指针:双向自动传播
  6. 知识点:
      A RS会测量设备的处理器数量,调用rsForEach函数就自动的在设备的多个处理器中划分工作。
      B 用__attribute__((kernel))自定义root函数。
      C 关于浮点精度的三个级别:#pragma rs_fp_full(IEEE 754-2008标准),#pragma rs_fp_relaxed,#pragma rs_fp_imprecise
      D 内嵌了一下实现:融合,模糊,颜 {MOD}矩阵,3x3卷积,5x5卷积,每个通道查找表,android YUV转rgb。
      E 在一个脚本里面通过调用rsForEach函数调用另个一个脚本,这时,UserData_t参数比较有用。
      F 用ScriptGroup.Builder创建Script Groups。
      G rs代码首先被llvm编译成字节码,然后在运行的时候,被另一个llvm编译成机器码
      H 关于包含指针的结构体。
  7. 实例(实现基于sobe的边缘检测): #include "rs_debug.rsh" #pragma version(1) #pragma rs java_package_name(com.android.rs) #pragma rs_fp_relaxed int32_t gWidth; int32_t gHeight; rs_allocation gIn; float gCoeffsY[9]={-1.f, 0.f, 1.f, -2.f, 0.f, 2.f, -1.f, 0.f, 1.f}; float gCoeffsX[9]={1.f, 2.f, 1.f,0.f, 0.f, 0.f, -1.f, -2.f, -1.f}; const static float3 gMonoMult = {0.299f, 0.587f, 0.114f}; void root(uchar4 *out, uint32_t x, uint32_t y) { uint32_t x1 = min((int32_t)x+1, gWidth); uint32_t x2 = max((int32_t)x-1, 0); uint32_t y1 = min((int32_t)y+1, gHeight); uint32_t y2 = max((int32_t)y-1, 0); float4 p00 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y1))[0]); float4 p01 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y1))[0]); float4 p02 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y1))[0]); float4 p10 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y))[0]); float4 p11 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y))[0]); float4 p12 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y))[0]); float4 p20 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y2))[0]); float4 p21 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y2))[0]); float4 p22 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y2))[0]); /* p00 *= gCoeffsX[0]; p01 *= gCoeffsX[1]; p02 *= gCoeffsX[2]; p10 *= gCoeffsX[3]; p11 *= gCoeffsX[4]; p12 *= gCoeffsX[5]; p20 *= gCoeffsX[6]; p21 *= gCoeffsX[7]; p22 *= gCoeffsX[8]; p00 += p01; p02 += p10; p11 += p12; p20 += p21; p22 += p00; p02 += p11; p20 += p22; p20 += p02; p20 = clamp(p20, 0.f, 255.f); *out = convert_uchar4(p20);*/ //for X float4 p00X = p00*gCoeffsX[0]; float4 p01X = p01*gCoeffsX[1]; float4 p02X = p02*gCoeffsX[2]; float4 p10X = p10*gCoeffsX[3]; float4 p11X = p11*gCoeffsX[4]; float4 p12X = p12*gCoeffsX[5]; float4 p20X = p20*gCoeffsX[6]; float4 p21X = p21*gCoeffsX[7]; float4 p22X = p22*gCoeffsX[8]; p00X += p01X; p02X += p10X; p11X += p12X; p20X += p21X; p22X += p00X; p02X += p11X; p20X += p22X; p20X += p02X; p20X = clamp(p20X, 0.f, 255.f); //for Y float4 p00Y = p00*gCoeffsY[0]; float4 p01Y = p01*gCoeffsY[1]; float4 p02Y = p02*gCoeffsY[2]; float4 p10Y = p10*gCoeffsY[3]; float4 p11Y = p11*gCoeffsY[4]; float4 p12Y = p12*gCoeffsY[5]; float4 p20Y = p20*gCoeffsY[6]; float4 p21Y = p21*gCoeffsY[7]; float4 p22Y = p22*gCoeffsY[8]; p00Y += p01Y; p02Y += p10Y; p11Y += p12Y; p20Y += p21Y; p22Y += p00Y; p02Y += p11Y; p20Y += p22Y; p20Y += p02Y; p20Y = clamp(p20Y, 0.f, 255.f); float4 finalValue=sqrt(p20X*p20X+p20Y*p20Y); /*float3 pixel = finalValue.rgb; finalValue.rgb.r-=10; finalValue.rgb.g-=10; finalValue.rgb.b-=10; finalValue.w=255.f; rsDebug("call times:", pixel.r,pixel.g,pixel.b);*/ //阀值判断,有点草率 /*if((finalValue.rgb.r+finalValue.rgb.g+finalValue.rgb.b)<90){ finalValue.rgb.r=0; finalValue.rgb.g=0; finalValue.rgb.b=0; }*/ *out = convert_uchar4(finalValue); }
  8. 相关源文件:
      SDK:platformsandroid-12 enderscriptinclude
      System:frameworksaselibs sscriptc
      rs doc:http://developer.android.com/guide/topics/renderscript/compute.html  Java API:http://developer.android.com/reference/android/renderscript/package-summary.html