1818#pragma rs java_package_name(com.android.rs.sample)
1919#include "rs_graphics.rsh"
2020
21- rs_sampler wrapUV;
22- rs_sampler clampUV;
23- rs_allocation sourceAlloc;
24- rs_allocation destAlloc;
21+ static rs_allocation sourceAlloc;
22+ static rs_allocation destAlloc;
23+ static rs_sampler allocSampler;
24+
25+ void setSampleData(rs_allocation dest, rs_allocation source, rs_sampler sampler) {
26+ destAlloc = dest;
27+ sourceAlloc = source;
28+ allocSampler = sampler;
29+ }
2530
26- static uint32_t wrapI(rs_sampler_value wrap, uint32_t coord, uint32_t size) {
31+ static int32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
2732 if (wrap == RS_SAMPLER_WRAP) {
28- return coord % (size + 1);
33+ coord = coord % size;
34+ if (coord < 0) {
35+ coord += size;
36+ }
2937 }
30- return min(coord, size);
38+ return max(0, min(coord, size - 1) );
3139}
3240
3341static 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)
3947 if (wrappedCoord.x == 0.0f && coord.x != 0.0f) {
4048 wrappedCoord.x = 1.0f;
4149 }
50+ if (wrappedCoord.x < 0.0f) {
51+ wrappedCoord.x += 1.0f;
52+ }
4253 } else {
43- wrappedCoord.x = min(coord.x, 1.0f);
54+ wrappedCoord.x = max(0.0f, min(coord.x, 1.0f) );
4455 }
4556
4657 if (wrapT == RS_SAMPLER_WRAP) {
@@ -49,14 +60,18 @@ static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord)
4960 if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
5061 wrappedCoord.y = 1.0f;
5162 }
63+ if (wrappedCoord.y < 0.0f) {
64+ wrappedCoord.y += 1.0f;
65+ }
5266 } else {
53- wrappedCoord.y = min(coord.y, 1.0f);
67+ wrappedCoord.y = max(0.0f, min(coord.y, 1.0f) );
5468 }
5569 return wrappedCoord;
5670}
5771
5872// Naive implementation of texture filtering for prototyping purposes
5973static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
74+ //rsDebug("*****************************************", 0);
6075 rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
6176 rs_sampler_value wrapT = rsgSamplerGetWrapT(s);
6277
@@ -65,26 +80,57 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
6580
6681 uv = wrap(wrapS, wrapT, uv);
6782
68- uint32_t sourceW = rsAllocationGetDimX(a) - 1;
69- uint32_t sourceH = rsAllocationGetDimY(a) - 1;
83+ int32_t sourceW = rsAllocationGetDimX(a);
84+ int32_t sourceH = rsAllocationGetDimY(a);
85+
86+ /*rsDebug("uv", uv);
87+ rsDebug("sourceW", sourceW);
88+ rsDebug("sourceH", sourceH);*/
7089
7190 float2 dimF;
7291 dimF.x = (float)(sourceW);
7392 dimF.y = (float)(sourceH);
7493 float2 pixelUV = uv * dimF;
75- uint2 iPixel = convert_uint2(pixelUV);
94+ int2 iPixel = convert_int2(pixelUV);
95+ /*rsDebug("iPixelX initial", iPixel.x);
96+ rsDebug("iPixelY initial", iPixel.y);*/
7697
7798 if (sampleMin == RS_SAMPLER_NEAREST ||
7899 sampleMag == RS_SAMPLER_NEAREST) {
100+ iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
101+ iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
79102 uchar4 *nearestSample = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
80103 return convert_float4(*nearestSample);
81104 }
82105
83106 float2 frac = pixelUV - convert_float2(iPixel);
107+
108+ if (frac.x < 0.5f) {
109+ iPixel.x -= 1;
110+ frac.x += 0.5f;
111+ } else {
112+ frac.x -= 0.5f;
113+ }
114+ if (frac.y < 0.5f) {
115+ iPixel.y -= 1;
116+ frac.y += 0.5f;
117+ } else {
118+ frac.y -= 0.5f;
119+ }
84120 float2 oneMinusFrac = 1.0f - frac;
85121
122+ float4 weights;
123+ weights.x = oneMinusFrac.x * oneMinusFrac.y;
124+ weights.y = frac.x * oneMinusFrac.y;
125+ weights.z = oneMinusFrac.x * frac.y;
126+ weights.w = frac.x * frac.y;
127+
86128 uint32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
87129 uint32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
130+ iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
131+ iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
132+ /*rsDebug("iPixelX wrapped", iPixel.x);
133+ rsDebug("iPixelY wrapped", iPixel.y);*/
88134
89135 uchar4 *p0c = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
90136 uchar4 *p1c = (uchar4*)rsGetElementAt(a, nextX, iPixel.y);
@@ -96,24 +142,9 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
96142 float4 p2 = convert_float4(*p2c);
97143 float4 p3 = convert_float4(*p3c);
98144
99- float4 weights;
100- weights.x = oneMinusFrac.x * oneMinusFrac.y;
101- weights.y = frac.x * oneMinusFrac.y;
102- weights.z = oneMinusFrac.x * frac.y;
103- weights.w = frac.x * frac.y;
104-
105145 float4 result = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;
106146
107- /*rsDebug("*****************************************", 0);
108- rsDebug("u", uv.x);
109- rsDebug("v", uv.y);
110- rsDebug("sourceW", sourceW);
111- rsDebug("sourceH", sourceH);
112- rsDebug("iPixelX", iPixel.x);
113- rsDebug("iPixelY", iPixel.y);
114- rsDebug("fiPixel", (float2)iPixel);
115- rsDebug("whole", wholeUV);
116- rsDebug("pixelUV", pixelUV);
147+ /*rsDebug("pixelUV", pixelUV);
117148 rsDebug("frac", frac);
118149 rsDebug("oneMinusFrac", oneMinusFrac);
119150 rsDebug("p0", p0);
@@ -131,15 +162,11 @@ void root(uchar4 *out, uint32_t x, uint32_t y) {
131162 float destX = (float)rsAllocationGetDimX(destAlloc) - 1.0f;
132163 float destY = (float)rsAllocationGetDimY(destAlloc) - 1.0f;
133164
134- /*rsDebug("*****************************************", 0);
135- rsDebug("x", x);
136- rsDebug("y", y);*/
137-
138165 float2 uv;
139166 uv.x = (float)x / destX;
140167 uv.y = (float)y / destY;
141168
142- out->xyz = convert_uchar3(sample(sourceAlloc, wrapUV , uv*2.0f).xyz);
169+ out->xyz = convert_uchar3(sample(sourceAlloc, allocSampler , uv*2.0f).xyz);
143170 out->w = 0xff;
144171}
145172
0 commit comments