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

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

Merge "Adding more modes to the sampler test app. Fixing pixel placement."

parents 761415bd e51ae262
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;
}