Search code examples
androidrenderscript

Why is my rendescript in android not working at all?


Here is my build.gradle file

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion '22.0.1'

    defaultConfig {
        applicationId "com.apps.foo.pointop"
        minSdkVersion 15
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}

I have a couple of classes as well:

This is called whenever there is an new frame from the camera (that means a lot of times!)

 @Override
    public void onCleanPreviewBitmapUpdated(Bitmap origBmp) {

        if(processedPreviewFragment != null) {
            processedPreviewFragment.setImageViewBitmap(
                    bProcessor.processBitmap(origBmp)
            );
        }
    }

Now my bProcessor class does this:

public Bitmap processBitmap(Bitmap origBmp) {
    return edgeDetection.apply(origBmp);
}

Quite simple.

My edgeDetection class has this:

package com.apps.foo.pointop;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v8.renderscript.*;

public class EdgeDetection {

    private Allocation inAllocation;
    private Allocation outAllocation;
    private RenderScript mRS = null;
    private ScriptC_edgedetect mScript = null;

    public EdgeDetection(Context ctx) {
        mRS = RenderScript.create(ctx);
        mScript = new ScriptC_edgedetect(mRS, ctx.getResources(), R.raw.edgedetect);
    }

    public Bitmap apply(Bitmap origBmp) {

        Bitmap bmpCopy = origBmp.copy(origBmp.getConfig(), true); // is this needed?

        inAllocation = Allocation.createFromBitmap(mRS, origBmp);
        outAllocation = Allocation.createFromBitmap(mRS, bmpCopy);

        mScript.forEach_root(inAllocation,outAllocation);

        return bmpCopy;
    }
}

Now lastly my RenderScript code is this (it does not do edge detection, I am just playing around with averaging the image for now):

#pragma version(1)
#pragma rs java_package_name(com.apps.foo.pointop)


uchar4 RS_KERNEL root(uchar4 in, uint32_t x, uint32_t y) {

  uchar4 out = in;
  float3 pixel = convert_float4(in).rgb;

  pixel.r = (pixel.r + pixel.g + pixel.b)/3;

  pixel.g = (pixel.r + pixel.g + pixel.b)/3;
  pixel.b = (pixel.r + pixel.g + pixel.b)/3;

  out.xyz = convert_uchar3(pixel);
  return out;
}

Now when I do run the code, there is nothing changed.... I even compare the new bitmap and it is exactly the same as the original one. Why is my renderscript running but no changes are applied?

I am testing this on a Samsung S4 mini, running KitKat 4.4.4.


Solution

  • After the forEach, you need to do:

    outAllocation.copyTo(bmpCopy);
    

    Without that, you aren't actually copying back the Allocation results that the forEach operated on. Bitmap Allocations often implicitly declare USAGE_SHARED, but that still necessitates the use of copyTo(), which might just be a no-op.