Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29e23920 authored by Alex Sakhartchouk's avatar Alex Sakhartchouk
Browse files

Support for more vector types.

Change-Id: I06d6e8814e75c0dcd726a3c95de82fd6f6267c4d
parent e51ae262
Loading
Loading
Loading
Loading
+22.5 KiB
Loading image diff...
+15 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.rs.sample;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.SurfaceTexture;
@@ -66,13 +67,14 @@ public class SampleRSActivity extends Activity {
    }

    private final String TAG = "Img";
    private Bitmap mBitmapIn;
    private TextureView mDisplayView;
    private Bitmap mBitmapTwoByTwo;
    private Bitmap mBitmapCity;

    private TextView mBenchmarkResult;

    private RenderScript mRS;
    private Allocation mInPixelsAllocation;
    private Allocation mTwoByTwoAlloc;
    private Allocation mCityAlloc;
    private ScriptC_sample mScript;

    public void onStartTrackingTouch(SeekBar seekBar) {
@@ -86,14 +88,18 @@ public class SampleRSActivity extends Activity {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rs);

        mBitmapIn = loadBitmap(R.drawable.twobytwo);
        mDisplayView = (TextureView) findViewById(R.id.display);
        mBitmapTwoByTwo = loadBitmap(R.drawable.twobytwo);
        mBitmapCity = loadBitmap(R.drawable.city);

        mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
        mBenchmarkResult.setText("Result: not run");

        mRS = RenderScript.create(this);
        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
        mTwoByTwoAlloc = Allocation.createFromBitmap(mRS, mBitmapTwoByTwo,
                                                          Allocation.MipmapControl.MIPMAP_NONE,
                                                          Allocation.USAGE_SCRIPT);

        mCityAlloc = Allocation.createFromBitmap(mRS, mBitmapCity,
                                                          Allocation.MipmapControl.MIPMAP_NONE,
                                                          Allocation.USAGE_SCRIPT);

@@ -101,8 +107,8 @@ public class SampleRSActivity extends Activity {

        int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT;

        int outX = 32;
        int outY = 32;
        int outX = 256;
        int outY = 256;

        // Wrap Linear
        Allocation outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
@@ -144,7 +150,7 @@ public class SampleRSActivity extends Activity {

    private synchronized void filterAlloc(Allocation alloc, Sampler sampler) {
        long t = java.lang.System.currentTimeMillis();
        mScript.invoke_setSampleData(alloc, mInPixelsAllocation, sampler);
        mScript.invoke_setSampleData(alloc, mTwoByTwoAlloc, sampler);
        mScript.forEach_root(alloc);
        alloc.ioSendOutput();
        mRS.finish();
+102 −61
Original line number Diff line number Diff line
@@ -38,39 +38,113 @@ static int32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
    return max(0, min(coord, size - 1));
}

static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord) {
    float2 wrappedCoord;
    float temp;
    if (wrapS == RS_SAMPLER_WRAP) {
        wrappedCoord.x = fract(coord.x, &temp);
        // Make sure that non zero integer uv's map to one
        if (wrappedCoord.x == 0.0f && coord.x != 0.0f) {
            wrappedCoord.x = 1.0f;
        }
        if (wrappedCoord.x < 0.0f) {
            wrappedCoord.x += 1.0f;
        }
    } else {
        wrappedCoord.x = max(0.0f, min(coord.x, 1.0f));
#define convert_float(v) (float)v
#define SAMPLE_1D_FUNC(vecsize)                                                                 \
        static float##vecsize get1DSample##vecsize(rs_allocation a, float2 weights,             \
                                                 int iPixel, int next) {                        \
            uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel);                   \
            uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, next);                     \
            float##vecsize p0 = convert_float##vecsize(*p0c);                                   \
            float##vecsize p1 = convert_float##vecsize(*p1c);                                   \
            return p0 * weights.x + p1 * weights.y;                                             \
        }
#define SAMPLE_2D_FUNC(vecsize)                                                                 \
        static float##vecsize get2DSample##vecsize(rs_allocation a, float4 weights,             \
                                                 int2 iPixel, int nextX, int nextY) {           \
            uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, iPixel.y);       \
            uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, nextX, iPixel.y);          \
            uchar##vecsize *p2c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, nextY);          \
            uchar##vecsize *p3c = (uchar##vecsize*)rsGetElementAt(a, nextX, nextY);             \
            float##vecsize p0 = convert_float##vecsize(*p0c);                                   \
            float##vecsize p1 = convert_float##vecsize(*p1c);                                   \
            float##vecsize p2 = convert_float##vecsize(*p2c);                                   \
            float##vecsize p3 = convert_float##vecsize(*p3c);                                   \
            return p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;           \
        }

SAMPLE_1D_FUNC()
SAMPLE_1D_FUNC(2)
SAMPLE_1D_FUNC(3)
SAMPLE_1D_FUNC(4)

SAMPLE_2D_FUNC()
SAMPLE_2D_FUNC(2)
SAMPLE_2D_FUNC(3)
SAMPLE_2D_FUNC(4)

static float4 getBilinearSample565(rs_allocation a, float4 weights,
                                   int2 iPixel, int nextX, int nextY) {
    float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
    return zero;
}

static float4 getBilinearSample(rs_allocation a, float4 weights,
                                int2 iPixel, int nextX, int nextY,
                                uint32_t vecSize, rs_data_type dt) {
    if (dt == RS_TYPE_UNSIGNED_5_6_5) {
        return getBilinearSample565(a, weights, iPixel, nextX, nextY);
    }

    float4 result;
    switch(vecSize) {
    case 1:
        result.x = get2DSample(a, weights, iPixel, nextX, nextY);
        result.yzw = 0.0f;
        break;
    case 2:
        result.xy = get2DSample2(a, weights, iPixel, nextX, nextY);
        result.zw = 0.0f;
        break;
    case 3:
        result.xyz = get2DSample3(a, weights, iPixel, nextX, nextY);
        result.w = 0.0f;
        break;
    case 4:
        result = get2DSample4(a, weights, iPixel, nextX, nextY);
        break;
    }

    if (wrapT == RS_SAMPLER_WRAP) {
        wrappedCoord.y = fract(coord.y, &temp);
        // Make sure that non zero integer uv's map to one
        if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
            wrappedCoord.y = 1.0f;
    return result;
}
        if (wrappedCoord.y < 0.0f) {
            wrappedCoord.y += 1.0f;

static float4 getNearestSample(rs_allocation a, int2 iPixel, uint32_t vecSize, rs_data_type dt) {
    if (dt == RS_TYPE_UNSIGNED_5_6_5) {
        float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
        return zero;
    }
    } else {
        wrappedCoord.y = max(0.0f, min(coord.y, 1.0f));

    float4 result;
    switch(vecSize) {
    case 1:
        result.x = convert_float(*((uchar*)rsGetElementAt(a, iPixel.x, iPixel.y)));
        result.yzw = 0.0f;
    case 2:
        result.xy = convert_float2(*((uchar2*)rsGetElementAt(a, iPixel.x, iPixel.y)));
        result.zw = 0.0f;
    case 3:
        result.xyz = convert_float3(*((uchar3*)rsGetElementAt(a, iPixel.x, iPixel.y)));
        result.w = 0.0f;
    case 4:
        result = convert_float4(*((uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y)));
    }
    return wrappedCoord;

    return result;
}


// Naive implementation of texture filtering for prototyping purposes
static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {

    // Find out what kind of input data we are sampling
    rs_element elem = rsAllocationGetElement(a);
    uint32_t vecSize = rsElementGetVectorSize(elem);
    rs_data_kind dk = rsElementGetDataKind(elem);
    rs_data_type dt = rsElementGetDataType(elem);

    if (dk == RS_KIND_USER || (dt != RS_TYPE_UNSIGNED_8 && dt != RS_TYPE_UNSIGNED_5_6_5)) {
        float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
        return zero;
    }
    //rsDebug("*****************************************", 0);
    rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
    rs_sampler_value wrapT = rsgSamplerGetWrapT(s);
@@ -78,29 +152,20 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
    rs_sampler_value sampleMin = rsgSamplerGetMinification(s);
    rs_sampler_value sampleMag = rsgSamplerGetMagnification(s);

    uv = wrap(wrapS, wrapT, uv);

    int32_t sourceW = rsAllocationGetDimX(a);
    int32_t sourceH = rsAllocationGetDimY(a);

    /*rsDebug("uv", uv);
    rsDebug("sourceW", sourceW);
    rsDebug("sourceH", sourceH);*/

    float2 dimF;
    dimF.x = (float)(sourceW);
    dimF.y = (float)(sourceH);
    float2 pixelUV = uv * dimF;
    int2 iPixel = convert_int2(pixelUV);
    /*rsDebug("iPixelX initial", iPixel.x);
    rsDebug("iPixelY initial", iPixel.y);*/

    if (sampleMin == RS_SAMPLER_NEAREST ||
        sampleMag == RS_SAMPLER_NEAREST) {
        iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
        iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
        uchar4 *nearestSample = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
        return convert_float4(*nearestSample);
        return getNearestSample(a, iPixel, vecSize, dt);
    }

    float2 frac = pixelUV - convert_float2(iPixel);
@@ -125,36 +190,12 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
    weights.z = oneMinusFrac.x * frac.y;
    weights.w = frac.x * frac.y;

    uint32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
    uint32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
    int32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
    int32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
    iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
    iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
    /*rsDebug("iPixelX wrapped", iPixel.x);
    rsDebug("iPixelY wrapped", iPixel.y);*/

    uchar4 *p0c = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
    uchar4 *p1c = (uchar4*)rsGetElementAt(a, nextX, iPixel.y);
    uchar4 *p2c = (uchar4*)rsGetElementAt(a, iPixel.x, nextY);
    uchar4 *p3c = (uchar4*)rsGetElementAt(a, nextX, nextY);

    float4 p0 = convert_float4(*p0c);
    float4 p1 = convert_float4(*p1c);
    float4 p2 = convert_float4(*p2c);
    float4 p3 = convert_float4(*p3c);

    float4 result = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;

    /*rsDebug("pixelUV", pixelUV);
    rsDebug("frac", frac);
    rsDebug("oneMinusFrac", oneMinusFrac);
    rsDebug("p0", p0);
    rsDebug("p1", p1);
    rsDebug("p2", p2);
    rsDebug("p3", p3);
    rsDebug("w", weights);
    rsDebug("result", result);*/

    return result;
    return getBilinearSample(a, weights, iPixel, nextX, nextY, vecSize, dt);
}

void root(uchar4 *out, uint32_t x, uint32_t y) {