Android的Renderscript学习总结

  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 内嵌了一下实现:融合,模糊,颜色矩阵,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:platforms\android-12\renderscript\include
      System:frameworks\base\libs\rs\scriptc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值