简体   繁体   English

RenderScript停止在Android Lollilop中工作

[英]RenderScript Stopped Working in Android Lollilop

I was developing an app in KitKat (4.4) and I recently flashed Lollipop on my device (5.1). 我正在KitKat(4.4)中开发一个应用程序,最近我在设备(5.1)上刷新了Lollipop。 My RenderScript Code seems that is has 'broken'. 我的RenderScript代码似乎已“损坏”。 I mean it compiles fine, but when I launch the app it is not doing what it is supposed to do. 我的意思是它可以正常编译,但是当我启动该应用程序时,它没有执行应有的功能。 I use it to do edge detection in parallel but it is not doing anything. 我使用它并行执行边缘检测,但是它什么也没做。 Previously on KitKat I could see the edges. 以前在KitKat上我可以看到边缘。 Now it renders what the camera sees, no effect, no edge detection. 现在,它渲染了摄像机看到的内容,没有效果,没有边缘检测。

Here is my Application Manifest: 这是我的申请清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="foo.bar"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="9" />

    <uses-feature android:name="android.hardware.camera" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!--uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /-->

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".LiveCameraActivity"
            android:screenOrientation="sensorLandscape" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Here is my app gradle build.gradle file: 这是我的应用程序gradle build.gradle文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 19
    buildToolsVersion '19.1.0'

    defaultConfig {
        applicationId "foo.bar"
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"

        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true //not applicable for rs targetapi 21+
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

And more or less this is how I call my RenderScript Code: 或多或少这就是我所说的RenderScript代码:

I have all my renderscript (.rs) files under the rs folder under main . 我的所有renderscript(.rs)文件都位于main下的rs文件夹下。

And in Java: 在Java中:

bmp = mTextureView.getBitmap();
bmpCopy = bmp.copy(bmp.getConfig(),true); //create a copy of the original
bitmapProcessor.processBmpEdgeDetect(bmp, bmpCopy); //I think this is where it breaks
mImageView.setImageBitmap(bmpCopy); // render result

Now bitmapProcessor.processBmpEdgeDetect() has this: 现在, bitmapProcessor.processBmpEdgeDetect()具有以下功能:

renderScriptEdgeDetectWrapper = new RenderScriptEdgeDetectWrapper(ctx);
renderScriptAvgOperWrapper.setInAllocation(bmp);
renderScriptAvgOperWrapper.setOutAllocation(bmpCopy);
renderScriptAvgOperWrapper.setScriptWidth(bmp.getWidth()-1);
renderScriptAvgOperWrapper.setScriptHeight(bmp.getHeight()-1);
renderScriptAvgOperWrapper.forEach_root();

And my renderScriptAvgOperWrapper is basically this: 我的renderScriptAvgOperWrapper基本上是这样的:

public class RenderScriptEdgeDetectWrapper {

    private Allocation inAllocation;
    private Allocation outAllocation;
    private RenderScript rs;
    private ScriptC_edgedetect edgeDetectScript;
    private Context ctx;


    public RenderScriptEdgeDetectWrapper(Context context){
        ctx = context;
        rs = RenderScript.create(ctx);
        edgeDetectScript = new ScriptC_edgedetect(rs, ctx.getResources(), R.raw.edgedetect);
    };

    public void setInAllocation(Bitmap bmp){
        inAllocation = Allocation.createFromBitmap(rs,bmp);
        edgeDetectScript.set_inPixels(inAllocation);
    };

    public void setOutAllocation(Bitmap bmp){
        outAllocation = Allocation.createFromBitmap(rs,bmp);
    };

    public void setScriptWidth(int scriptWidth) {
        edgeDetectScript.set_width(scriptWidth);
    }

    public void setScriptHeight(int scriptHeight) {
        edgeDetectScript.set_height(scriptHeight);
    }

    public void forEach_root(){
        edgeDetectScript.forEach_root(inAllocation,outAllocation);
    }
}

It is just a simple wrapper. 这只是一个简单的包装。

Finally my renderScript edgedetect.rs file is this: 最后,我的renderScript edgedetect.rs文件是这样的:

#pragma version(1)
#pragma rs java_package_name(foo.bar)

rs_allocation inPixels;
int height;
int width;

void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
    float3 pixel = convert_float4(in[0]).rgb;

    if(x==0 || x==width || y==0 || y==height){
        pixel.r = 0;
        pixel.g = 191;
        pixel.b = 255;
    }else{ //do image processing here

        float3 pixelNH = convert_float4(rsGetElementAt_uchar4(inPixels, x+1, y)).rgb;
        float3 pixelNV = convert_float4(rsGetElementAt_uchar4(inPixels, x, y+1)).rgb;

        int grayAvg = (pixel.r + pixel.g + pixel.b)/3;
        int grayAvgNH = (pixelNH.r + pixelNH.g + pixelNH.b)/3;
        int grayAvgNV = (pixelNV.r + pixelNV.g + pixelNV.b)/3;

        int edgeOperatorValue = 2*grayAvg - grayAvgNH - grayAvgNV;

        if(edgeOperatorValue < 0){
            edgeOperatorValue = -1 * edgeOperatorValue;
        };

        pixel.r = edgeOperatorValue;
        pixel.g = edgeOperatorValue;
        pixel.b = edgeOperatorValue;
    };

    out->xyz = convert_uchar3(pixel);
}

Now I do not understand why this code worked fine in KitKat but fails completely in Lollipop. 现在我不明白为什么这段代码在KitKat上能正常工作,而在Lollipop中却完全失败。 If you could guide in what is wrong that would be great. 如果您可以指导哪里出了问题,那将很棒。 Thanks. 谢谢。

While you are calling forEach with renderScriptAvgOperWrapper, you are never actually copying the resulting output Allocation back into the bitmap you are drawing. 当您使用renderScriptAvgOperWrapper调用forEach时,您实际上从未将结果输出分配复制回您要绘制的位图中。 You need to do an explicit "Allocation.copyTo(Bitmap)" operation after the forEach. 您需要在forEach之后执行一个明确的“ Allocation.copyTo(Bitmap)”操作。 The Allocation should be your output Allocation that you just wrote, and Bitmap is what you want to draw it to. “分配”应该是您刚刚编写的输出“分配”,而“位图”就是要绘制到的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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