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

Commit e51ae262 authored by Alex Sakhartchouk's avatar Alex Sakhartchouk
Browse files

Adding more modes to the sampler test app.

Fixing pixel placement.

Change-Id: I355cc611ebe0bfb15af96cc498604d9b9fa1a9d3
parent 43ca3cfa
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -26,10 +26,42 @@
                android:orientation="vertical"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
            <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textSize="8pt"
                        android:text="@string/wraplinear"/>
            <TextureView
                android:id="@+id/display"
                android:layout_width="256sp"
                android:layout_height="256sp" />
            <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textSize="8pt"
                        android:text="@string/clamplinear"/>
            <TextureView
                android:id="@+id/display2"
                android:layout_width="256sp"
                android:layout_height="256sp" />
            <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textSize="8pt"
                        android:text="@string/wrapnearest"/>
            <TextureView
                android:id="@+id/display3"
                android:layout_width="256sp"
                android:layout_height="256sp" />
            <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textSize="8pt"
                        android:text="@string/clampnearest"/>
            <TextureView
                android:id="@+id/display4"
                android:layout_width="256sp"
                android:layout_height="256sp" />
            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="horizontal"
                android:layout_width="fill_parent"
+4 −0
Original line number Diff line number Diff line
@@ -21,4 +21,8 @@
    <!-- General -->
    <skip />
    <string name="benchmark">Benchmark</string>
    <string name="wraplinear">Wrap Linear</string>
    <string name="clamplinear">Clamp Linear</string>
    <string name="wrapnearest">Wrap Nearest</string>
    <string name="clampnearest">Clamp Nearest</string>
</resources>
+64 −41
Original line number Diff line number Diff line
@@ -31,14 +31,40 @@ import android.renderscript.Type;
import android.renderscript.Type.Builder;
import android.util.Log;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

public class SampleRSActivity extends Activity
                              implements TextureView.SurfaceTextureListener
{
public class SampleRSActivity extends Activity {
    class TextureViewUpdater implements TextureView.SurfaceTextureListener {
        private Allocation mOutPixelsAllocation;
        private Sampler mSampler;

        TextureViewUpdater(Allocation outAlloc, Sampler sampler) {
            mOutPixelsAllocation = outAlloc;
            mSampler = sampler;
        }

        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        }

        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            mOutPixelsAllocation.setSurfaceTexture(surface);
        }

        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            mOutPixelsAllocation.setSurfaceTexture(surface);
            filterAlloc(mOutPixelsAllocation, mSampler);
        }

        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            mOutPixelsAllocation.setSurfaceTexture(null);
            return true;
        }
    }

    private final String TAG = "Img";
    private Bitmap mBitmapIn;
    private TextureView mDisplayView;
@@ -47,7 +73,6 @@ public class SampleRSActivity extends Activity

    private RenderScript mRS;
    private Allocation mInPixelsAllocation;
    private Allocation mOutPixelsAllocation;
    private ScriptC_sample mScript;

    public void onStartTrackingTouch(SeekBar seekBar) {
@@ -74,17 +99,36 @@ public class SampleRSActivity extends Activity

        Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));

        mOutPixelsAllocation = Allocation.createTyped(mRS, b.setX(32).setY(32).create(),
                                                      Allocation.USAGE_SCRIPT |
                                                      Allocation.USAGE_IO_OUTPUT);
        mDisplayView.setSurfaceTextureListener(this);
        int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT;

        mScript = new ScriptC_sample(mRS, getResources(), R.raw.sample);
        int outX = 32;
        int outY = 32;

        // Wrap Linear
        Allocation outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
        TextureViewUpdater updater = new TextureViewUpdater(outAlloc, Sampler.WRAP_LINEAR(mRS));
        TextureView displayView = (TextureView) findViewById(R.id.display);
        displayView.setSurfaceTextureListener(updater);

        // Clamp Linear
        outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
        updater = new TextureViewUpdater(outAlloc, Sampler.CLAMP_LINEAR(mRS));
        displayView = (TextureView) findViewById(R.id.display2);
        displayView.setSurfaceTextureListener(updater);

        mScript.set_sourceAlloc(mInPixelsAllocation);
        mScript.set_destAlloc(mOutPixelsAllocation);
        mScript.set_wrapUV(Sampler.WRAP_LINEAR(mRS));
        mScript.set_clampUV(Sampler.CLAMP_LINEAR(mRS));
        // Wrap Nearest
        outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
        updater = new TextureViewUpdater(outAlloc, Sampler.WRAP_NEAREST(mRS));
        displayView = (TextureView) findViewById(R.id.display3);
        displayView.setSurfaceTextureListener(updater);

        // Clamp Nearest
        outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
        updater = new TextureViewUpdater(outAlloc, Sampler.CLAMP_NEAREST(mRS));
        displayView = (TextureView) findViewById(R.id.display4);
        displayView.setSurfaceTextureListener(updater);

        mScript = new ScriptC_sample(mRS, getResources(), R.raw.sample);
    }

    private Bitmap loadBitmap(int resource) {
@@ -98,43 +142,22 @@ public class SampleRSActivity extends Activity
        return b2;
    }

    private void filter() {
    private synchronized void filterAlloc(Allocation alloc, Sampler sampler) {
        long t = java.lang.System.currentTimeMillis();
        mScript.forEach_root(mOutPixelsAllocation);
        mOutPixelsAllocation.ioSendOutput();
        mScript.invoke_setSampleData(alloc, mInPixelsAllocation, sampler);
        mScript.forEach_root(alloc);
        alloc.ioSendOutput();
        mRS.finish();
        t = java.lang.System.currentTimeMillis() - t;
        Log.i(TAG, "Filter time is: " + t + " ms");
    }

    public void benchmark(View v) {
        filter();
        /*filterAlloc();
        long t = java.lang.System.currentTimeMillis();
        filter();
        filterAlloc();
        t = java.lang.System.currentTimeMillis() - t;
        mDisplayView.invalidate();
        mBenchmarkResult.setText("Result: " + t + " ms");
    }


    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mOutPixelsAllocation.setSurfaceTexture(surface);
        filter();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        mOutPixelsAllocation.setSurfaceTexture(surface);
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mOutPixelsAllocation.setSurfaceTexture(null);
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        mBenchmarkResult.setText("Result: " + t + " ms");*/
    }
}
+60 −33
Original line number Diff line number Diff line
@@ -18,16 +18,24 @@
#pragma rs java_package_name(com.android.rs.sample)
#include "rs_graphics.rsh"

rs_sampler wrapUV;
rs_sampler clampUV;
rs_allocation sourceAlloc;
rs_allocation destAlloc;
static rs_allocation sourceAlloc;
static rs_allocation destAlloc;
static rs_sampler allocSampler;

void setSampleData(rs_allocation dest, rs_allocation source, rs_sampler sampler) {
    destAlloc = dest;
    sourceAlloc = source;
    allocSampler = sampler;
}

static uint32_t wrapI(rs_sampler_value wrap, uint32_t coord, uint32_t size) {
static int32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
    if (wrap == RS_SAMPLER_WRAP) {
        return coord % (size + 1);
        coord = coord % size;
        if (coord < 0) {
            coord += size;
        }
    }
    return min(coord, size);
    return max(0, min(coord, size - 1));
}

static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord) {
@@ -39,8 +47,11 @@ static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord)
        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 = min(coord.x, 1.0f);
        wrappedCoord.x = max(0.0f, min(coord.x, 1.0f));
    }

    if (wrapT == RS_SAMPLER_WRAP) {
@@ -49,14 +60,18 @@ static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord)
        if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
            wrappedCoord.y = 1.0f;
        }
        if (wrappedCoord.y < 0.0f) {
            wrappedCoord.y += 1.0f;
        }
    } else {
        wrappedCoord.y = min(coord.y, 1.0f);
        wrappedCoord.y = max(0.0f, min(coord.y, 1.0f));
    }
    return wrappedCoord;
}

// Naive implementation of texture filtering for prototyping purposes
static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
    //rsDebug("*****************************************", 0);
    rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
    rs_sampler_value wrapT = rsgSamplerGetWrapT(s);

@@ -65,26 +80,57 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {

    uv = wrap(wrapS, wrapT, uv);

    uint32_t sourceW = rsAllocationGetDimX(a) - 1;
    uint32_t sourceH = rsAllocationGetDimY(a) - 1;
    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;
    uint2 iPixel = convert_uint2(pixelUV);
    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);
    }

    float2 frac = pixelUV - convert_float2(iPixel);

    if (frac.x < 0.5f) {
        iPixel.x -= 1;
        frac.x += 0.5f;
    } else {
        frac.x -= 0.5f;
    }
    if (frac.y < 0.5f) {
        iPixel.y -= 1;
        frac.y += 0.5f;
    } else {
        frac.y -= 0.5f;
    }
    float2 oneMinusFrac = 1.0f - frac;

    float4 weights;
    weights.x = oneMinusFrac.x * oneMinusFrac.y;
    weights.y = frac.x * oneMinusFrac.y;
    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);
    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);
@@ -96,24 +142,9 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
    float4 p2 = convert_float4(*p2c);
    float4 p3 = convert_float4(*p3c);

    float4 weights;
    weights.x = oneMinusFrac.x * oneMinusFrac.y;
    weights.y = frac.x * oneMinusFrac.y;
    weights.z = oneMinusFrac.x * frac.y;
    weights.w = frac.x * frac.y;

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

    /*rsDebug("*****************************************", 0);
    rsDebug("u", uv.x);
    rsDebug("v", uv.y);
    rsDebug("sourceW", sourceW);
    rsDebug("sourceH", sourceH);
    rsDebug("iPixelX", iPixel.x);
    rsDebug("iPixelY", iPixel.y);
    rsDebug("fiPixel", (float2)iPixel);
    rsDebug("whole", wholeUV);
    rsDebug("pixelUV", pixelUV);
    /*rsDebug("pixelUV", pixelUV);
    rsDebug("frac", frac);
    rsDebug("oneMinusFrac", oneMinusFrac);
    rsDebug("p0", p0);
@@ -131,15 +162,11 @@ void root(uchar4 *out, uint32_t x, uint32_t y) {
    float destX = (float)rsAllocationGetDimX(destAlloc) - 1.0f;
    float destY = (float)rsAllocationGetDimY(destAlloc) - 1.0f;

    /*rsDebug("*****************************************", 0);
    rsDebug("x", x);
    rsDebug("y", y);*/

    float2 uv;
    uv.x = (float)x / destX;
    uv.y = (float)y / destY;

    out->xyz = convert_uchar3(sample(sourceAlloc, wrapUV, uv*2.0f).xyz);
    out->xyz = convert_uchar3(sample(sourceAlloc, allocSampler, uv*2.0f).xyz);
    out->w = 0xff;
}