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

Commit c7092163 authored by Alex Sakhartchouk's avatar Alex Sakhartchouk Committed by Android (Google) Code Review
Browse files

Merge "Support for more vector types."

parents c31424e6 29e23920
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) {