15b539461dcc159bd89297443780d635ccc5e3564John Hoford/*
25b539461dcc159bd89297443780d635ccc5e3564John Hoford * Copyright (C) 2015 The Android Open Source Project
35b539461dcc159bd89297443780d635ccc5e3564John Hoford *
45b539461dcc159bd89297443780d635ccc5e3564John Hoford * Licensed under the Apache License, Version 2.0 (the "License");
55b539461dcc159bd89297443780d635ccc5e3564John Hoford * you may not use this file except in compliance with the License.
65b539461dcc159bd89297443780d635ccc5e3564John Hoford * You may obtain a copy of the License at
75b539461dcc159bd89297443780d635ccc5e3564John Hoford *
85b539461dcc159bd89297443780d635ccc5e3564John Hoford *      http://www.apache.org/licenses/LICENSE-2.0
95b539461dcc159bd89297443780d635ccc5e3564John Hoford *
105b539461dcc159bd89297443780d635ccc5e3564John Hoford * Unless required by applicable law or agreed to in writing, software
115b539461dcc159bd89297443780d635ccc5e3564John Hoford * distributed under the License is distributed on an "AS IS" BASIS,
125b539461dcc159bd89297443780d635ccc5e3564John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135b539461dcc159bd89297443780d635ccc5e3564John Hoford * See the License for the specific language governing permissions and
145b539461dcc159bd89297443780d635ccc5e3564John Hoford * limitations under the License.
155b539461dcc159bd89297443780d635ccc5e3564John Hoford */
165b539461dcc159bd89297443780d635ccc5e3564John Hoford
175b539461dcc159bd89297443780d635ccc5e3564John Hoford#pragma version(1)
185b539461dcc159bd89297443780d635ccc5e3564John Hoford#pragma rs java_package_name(com.example.android.rs.vr.engine)
195b539461dcc159bd89297443780d635ccc5e3564John Hoford#pragma rs_fp_relaxed
205b539461dcc159bd89297443780d635ccc5e3564John Hoford
215b539461dcc159bd89297443780d635ccc5e3564John Hoford#define FLOAT_MAX  3.4028234E30f
225b539461dcc159bd89297443780d635ccc5e3564John Hoford
235b539461dcc159bd89297443780d635ccc5e3564John Hofordfloat vert[3 * 8];
245b539461dcc159bd89297443780d635ccc5e3564John Hofordint index[3 * 12];
255b539461dcc159bd89297443780d635ccc5e3564John Hofordint width;
265b539461dcc159bd89297443780d635ccc5e3564John Hofordint height;
275b539461dcc159bd89297443780d635ccc5e3564John Hoford
285b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic float zoff[12];
295b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic float2 slope[12];
305b539461dcc159bd89297443780d635ccc5e3564John Hoford
315b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic float2 p1[12];
325b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic float2 p2[12];
335b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic float2 p3[12];
345b539461dcc159bd89297443780d635ccc5e3564John Hoford
355b539461dcc159bd89297443780d635ccc5e3564John Hoford      float2 d12[12];
365b539461dcc159bd89297443780d635ccc5e3564John Hoford        float2 d23[12];
375b539461dcc159bd89297443780d635ccc5e3564John Hoford        float2 d31[12];
385b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic int total;
395b539461dcc159bd89297443780d635ccc5e3564John Hoford
405b539461dcc159bd89297443780d635ccc5e3564John Hofordstatic void
415b539461dcc159bd89297443780d635ccc5e3564John HofordtriangleSetup(float3 f1, float3 f2, float3 f3) {
425b539461dcc159bd89297443780d635ccc5e3564John Hoford    if (((f1.x - f2.x) * (f3.y - f2.y) - (f1.y - f2.y) * (f3.x - f2.x)) < 0) {
435b539461dcc159bd89297443780d635ccc5e3564John Hoford        float3 tmp = f1;
445b539461dcc159bd89297443780d635ccc5e3564John Hoford        f1 = f2;
455b539461dcc159bd89297443780d635ccc5e3564John Hoford        f2 = tmp;
465b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
475b539461dcc159bd89297443780d635ccc5e3564John Hoford
485b539461dcc159bd89297443780d635ccc5e3564John Hoford    // using maxmima
495b539461dcc159bd89297443780d635ccc5e3564John Hoford    // string(solve([x1*dx+y1*dy+zoff=z1,x2*dx+y2*dy+zoff=z2,x3*dx+y3*dy+zoff=z3],[dx,dy,zoff]));
505b539461dcc159bd89297443780d635ccc5e3564John Hoford    double d = (f1.x * (f3.y - f2.y) - f2.x * f3.y + f3.x * f2.y + (f2.x - f3.x)
515b539461dcc159bd89297443780d635ccc5e3564John Hoford            * f1.y);
525b539461dcc159bd89297443780d635ccc5e3564John Hoford
535b539461dcc159bd89297443780d635ccc5e3564John Hoford    if (d == 0) {
545b539461dcc159bd89297443780d635ccc5e3564John Hoford        return;
555b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
565b539461dcc159bd89297443780d635ccc5e3564John Hoford
575b539461dcc159bd89297443780d635ccc5e3564John Hoford    slope[total].x = (-(f1.y * (f3.z - f2.z) - f2.y * f3.z + f3.y * f2.z + (f2.y - f3.y) * f1.z)
585b539461dcc159bd89297443780d635ccc5e3564John Hoford            / d);
595b539461dcc159bd89297443780d635ccc5e3564John Hoford    slope[total].y = ((f1.x * (f3.z - f2.z) - f2.x * f3.z + f3.x * f2.z + (f2.x - f3.x) * f1.z)
605b539461dcc159bd89297443780d635ccc5e3564John Hoford            / d);
615b539461dcc159bd89297443780d635ccc5e3564John Hoford    zoff[total] = ((f1.x * (f3.y * f2.z - f2.y * f3.z) + f1.y * (f2.x * f3.z - f3.x * f2.z) +
625b539461dcc159bd89297443780d635ccc5e3564John Hoford            (f3.x * f2.y - f2.x * f3.y) * f1.z) / d);
635b539461dcc159bd89297443780d635ccc5e3564John Hoford
645b539461dcc159bd89297443780d635ccc5e3564John Hoford    p1[total] = f1.xy;
655b539461dcc159bd89297443780d635ccc5e3564John Hoford    p2[total] = f2.xy;
665b539461dcc159bd89297443780d635ccc5e3564John Hoford    p3[total] = f3.xy;
675b539461dcc159bd89297443780d635ccc5e3564John Hoford    d12[total] = p1[total] - p2[total];
685b539461dcc159bd89297443780d635ccc5e3564John Hoford    d23[total] = p2[total] - p3[total];
695b539461dcc159bd89297443780d635ccc5e3564John Hoford    d31[total] = p3[total] - p1[total];
705b539461dcc159bd89297443780d635ccc5e3564John Hoford    total++;
715b539461dcc159bd89297443780d635ccc5e3564John Hoford}
725b539461dcc159bd89297443780d635ccc5e3564John Hoford
735b539461dcc159bd89297443780d635ccc5e3564John Hofordvoid setup_triangles(int w, int h) {
745b539461dcc159bd89297443780d635ccc5e3564John Hoford    width = w;
755b539461dcc159bd89297443780d635ccc5e3564John Hoford    height = h;
765b539461dcc159bd89297443780d635ccc5e3564John Hoford    total = 0;
775b539461dcc159bd89297443780d635ccc5e3564John Hoford    //   rsDebug("RRRRR >>>>>> setup_triangles ", w, h);
785b539461dcc159bd89297443780d635ccc5e3564John Hoford    float3 f1;
795b539461dcc159bd89297443780d635ccc5e3564John Hoford    float3 f2;
805b539461dcc159bd89297443780d635ccc5e3564John Hoford    float3 f3;
815b539461dcc159bd89297443780d635ccc5e3564John Hoford    for (int i = 0; i < 3 * 12; i += 3) {
825b539461dcc159bd89297443780d635ccc5e3564John Hoford        int p1 = index[i];
835b539461dcc159bd89297443780d635ccc5e3564John Hoford        int p2 = index[i + 1];
845b539461dcc159bd89297443780d635ccc5e3564John Hoford        int p3 = index[i + 2];
855b539461dcc159bd89297443780d635ccc5e3564John Hoford        f1.x = vert[p1];
865b539461dcc159bd89297443780d635ccc5e3564John Hoford        f1.y = vert[p1 + 1];
875b539461dcc159bd89297443780d635ccc5e3564John Hoford        f1.z = vert[p1 + 2];
885b539461dcc159bd89297443780d635ccc5e3564John Hoford        f2.x = vert[p2];
895b539461dcc159bd89297443780d635ccc5e3564John Hoford        f2.y = vert[p2 + 1];
905b539461dcc159bd89297443780d635ccc5e3564John Hoford        f2.z = vert[p2 + 2];
915b539461dcc159bd89297443780d635ccc5e3564John Hoford        f3.x = vert[p3];
925b539461dcc159bd89297443780d635ccc5e3564John Hoford        f3.y = vert[p3 + 1];
935b539461dcc159bd89297443780d635ccc5e3564John Hoford        f3.z = vert[p3 + 2];
945b539461dcc159bd89297443780d635ccc5e3564John Hoford        triangleSetup(f1, f2, f3);
955b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
965b539461dcc159bd89297443780d635ccc5e3564John Hoford}
975b539461dcc159bd89297443780d635ccc5e3564John Hoford
985b539461dcc159bd89297443780d635ccc5e3564John Hoford
995b539461dcc159bd89297443780d635ccc5e3564John Hofordfloat2 __attribute__ ((kernel)) render_z(uint32_t x, uint32_t y) {
1005b539461dcc159bd89297443780d635ccc5e3564John Hoford    float2 out = (float2) {FLOAT_MAX,-FLOAT_MAX};
1015b539461dcc159bd89297443780d635ccc5e3564John Hoford    float2 loc;
1025b539461dcc159bd89297443780d635ccc5e3564John Hoford    loc.x = x;
1035b539461dcc159bd89297443780d635ccc5e3564John Hoford    loc.y = y;
1045b539461dcc159bd89297443780d635ccc5e3564John Hoford    for (int i = 0; i < total; i++) {
1055b539461dcc159bd89297443780d635ccc5e3564John Hoford        float2 d1 = loc - p1[i];
1065b539461dcc159bd89297443780d635ccc5e3564John Hoford        float2 d2 = loc - p2[i];
1075b539461dcc159bd89297443780d635ccc5e3564John Hoford        float2 d3 = loc - p3[i];
1085b539461dcc159bd89297443780d635ccc5e3564John Hoford
1095b539461dcc159bd89297443780d635ccc5e3564John Hoford        float test1 = (d12[i].x) * (d1.y) - (d12[i].y) * (d1.x);
1105b539461dcc159bd89297443780d635ccc5e3564John Hoford        float test2 = (d23[i].x) * (d2.y) - (d23[i].y) * (d2.x);
1115b539461dcc159bd89297443780d635ccc5e3564John Hoford        float test3 = (d31[i].x) * (d3.y) - (d31[i].y) * (d3.x);
1125b539461dcc159bd89297443780d635ccc5e3564John Hoford        // float test = edge(0 , test1) * edge(0 , test2)* edge(0 , test3);
1135b539461dcc159bd89297443780d635ccc5e3564John Hoford
1145b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (test1 >= 0 &&
1155b539461dcc159bd89297443780d635ccc5e3564John Hoford                test2 >= 0 &&
1165b539461dcc159bd89297443780d635ccc5e3564John Hoford                test3 >= 0) {
1175b539461dcc159bd89297443780d635ccc5e3564John Hoford            float2 delta = slope[i] * loc;
1185b539461dcc159bd89297443780d635ccc5e3564John Hoford            float z = zoff[i] + delta.x + delta.y;
1195b539461dcc159bd89297443780d635ccc5e3564John Hoford
1205b539461dcc159bd89297443780d635ccc5e3564John Hoford            out.x = min(z, out.x);
1215b539461dcc159bd89297443780d635ccc5e3564John Hoford            out.y = max(z, out.y);
1225b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1235b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1245b539461dcc159bd89297443780d635ccc5e3564John Hoford    return out;
1255b539461dcc159bd89297443780d635ccc5e3564John Hoford}
1265b539461dcc159bd89297443780d635ccc5e3564John Hoford
1275b539461dcc159bd89297443780d635ccc5e3564John Hoford
1285b539461dcc159bd89297443780d635ccc5e3564John Hofordrs_allocation z_range_buff;
1295b539461dcc159bd89297443780d635ccc5e3564John Hofordfloat min_z = 1500;
1305b539461dcc159bd89297443780d635ccc5e3564John Hofordfloat max_z = 2300;
1315b539461dcc159bd89297443780d635ccc5e3564John Hoford
1325b539461dcc159bd89297443780d635ccc5e3564John Hofordvoid getMinMax() {
1335b539461dcc159bd89297443780d635ccc5e3564John Hoford
1345b539461dcc159bd89297443780d635ccc5e3564John Hoford    float tmp_min = FLOAT_MAX;
1355b539461dcc159bd89297443780d635ccc5e3564John Hoford    float tmp_max = -FLOAT_MAX;;
1365b539461dcc159bd89297443780d635ccc5e3564John Hoford    for (int y = 0; y < height; y++) {
1375b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int x = 0; x < width; x++) {
1385b539461dcc159bd89297443780d635ccc5e3564John Hoford            float2 v = rsGetElementAt_float2(z_range_buff, x, y);
1395b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (v.x == FLOAT_MAX) {
1405b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
1415b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
1425b539461dcc159bd89297443780d635ccc5e3564John Hoford            tmp_min = min(tmp_min, v.x);
1435b539461dcc159bd89297443780d635ccc5e3564John Hoford            tmp_max = max(tmp_max, v.x);
1445b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1455b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1465b539461dcc159bd89297443780d635ccc5e3564John Hoford    min_z = tmp_min;
1475b539461dcc159bd89297443780d635ccc5e3564John Hoford    max_z = tmp_max;
1485b539461dcc159bd89297443780d635ccc5e3564John Hoford    rsDebug("RRRRR >>>>>> getMinMax ", min_z, max_z);
1495b539461dcc159bd89297443780d635ccc5e3564John Hoford}
1505b539461dcc159bd89297443780d635ccc5e3564John Hoford
1515b539461dcc159bd89297443780d635ccc5e3564John Hoforduchar4 __attribute__ ((kernel)) draw_z_buffer(float2 in) {
1525b539461dcc159bd89297443780d635ccc5e3564John Hoford
1535b539461dcc159bd89297443780d635ccc5e3564John Hoford    if (in.x != FLOAT_MAX) {
1545b539461dcc159bd89297443780d635ccc5e3564John Hoford        uchar v = (uchar)(255 * (in.x - min_z) / (max_z - min_z));
1555b539461dcc159bd89297443780d635ccc5e3564John Hoford        uchar4 out;
1565b539461dcc159bd89297443780d635ccc5e3564John Hoford        out.r = v;
1575b539461dcc159bd89297443780d635ccc5e3564John Hoford        out.g = v;
1585b539461dcc159bd89297443780d635ccc5e3564John Hoford        out.b = v;
1595b539461dcc159bd89297443780d635ccc5e3564John Hoford        out.a = 255;
1605b539461dcc159bd89297443780d635ccc5e3564John Hoford        return out;
1615b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1625b539461dcc159bd89297443780d635ccc5e3564John Hoford
1635b539461dcc159bd89297443780d635ccc5e3564John Hoford    uchar4 out;
1645b539461dcc159bd89297443780d635ccc5e3564John Hoford    out.r = 0x44;
1655b539461dcc159bd89297443780d635ccc5e3564John Hoford    out.g = 0x44;
1665b539461dcc159bd89297443780d635ccc5e3564John Hoford    out.b = 0x99;
1675b539461dcc159bd89297443780d635ccc5e3564John Hoford    out.a = 255;
1685b539461dcc159bd89297443780d635ccc5e3564John Hoford    return out;
1695b539461dcc159bd89297443780d635ccc5e3564John Hoford}