Home | History | Annotate | Download | only in engine
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #pragma version(1)
     18 #pragma rs java_package_name(com.example.android.rs.vr.engine)
     19 #pragma rs_fp_relaxed
     20 
     21 int brick_dimx;
     22 int brick_dimy;
     23 int brick_dimz;
     24 rs_allocation volume;
     25 rs_allocation opacity;
     26 int z_offset;
     27 // output a single bit per pixel volume based on opacity
     28 
     29 uint __attribute__((kernel)) pack_chunk(uint32_t x) {
     30 
     31     int brick = x / (32 * 32);
     32     int bx = brick % brick_dimx;
     33     int yz = brick / brick_dimx;
     34     int by = yz % brick_dimy;
     35     int bz = yz / brick_dimy;
     36 
     37     int in_brick = x % (32 * 32);
     38     int in_br_y = in_brick % 32;
     39     int in_br_z = in_brick / 32;
     40     int pz = (bz << 5) | in_br_z;
     41 
     42 
     43      int py = (by << 5) | in_br_y;
     44 
     45     uint out = 0;
     46 
     47     if (pz >= rsAllocationGetDimZ(volume)) {
     48          return out;
     49     }
     50     if (py >= rsAllocationGetDimY(volume)) {
     51               return out;
     52     }
     53     for (int in_br_x = 0; in_br_x < 32; in_br_x++) {
     54         int px = (bx << 5) | in_br_x;
     55 
     56 
     57         int intensity = 0xFFFF & rsGetElementAt_short(volume, px, py, pz);
     58         uchar op = rsGetElementAt_uchar(opacity, intensity);
     59         uint v = (op > 0) ? 1 : 0;
     60         out |= v << in_br_x;
     61     }
     62     return out;
     63 }
     64 rs_allocation bricks; // input bricks
     65 
     66 uint __attribute__((kernel)) dilate(uint in, uint32_t x) {
     67 
     68     int BRICK_SIZE = 32 * 32;
     69     int brick = x / (BRICK_SIZE);
     70     int bx = brick % brick_dimx;
     71     int yz = brick / brick_dimx;
     72     int by = yz % brick_dimy;
     73     int bz = yz / brick_dimy;
     74 
     75     int in_brick = x % (BRICK_SIZE);
     76     int in_br_y = in_brick % 32;
     77     int in_br_z = in_brick / 32;
     78     uint slice;
     79     uint out = in;
     80     out |= in >> 1;
     81     out |= in << 1;
     82     int base_brick = bx + (by + brick_dimy * bz) * brick_dimx;
     83     int base_offset = (in_br_z) * 32 + (in_br_y);
     84 
     85       int slice_pos = base_brick * BRICK_SIZE + base_offset;
     86 
     87       // +/- in x
     88       if (bx > 0) {
     89         slice =   0x80000000 & rsGetElementAt_uint(bricks, slice_pos - BRICK_SIZE);
     90         out |= slice >> 31;
     91       }
     92       if (bx < brick_dimx - 1) {
     93         slice =  1  & rsGetElementAt_uint(bricks, slice_pos + BRICK_SIZE);
     94          out |= slice << 31;
     95       }
     96 
     97       // - in Y
     98       int off_neg_y = -1; // simple case -1 slice;
     99       if (in_br_y == 0) { // att the edge in brick go to y-1 brick
    100         if (by > 0) { // edge of screen
    101           off_neg_y = 31 - BRICK_SIZE * brick_dimx;
    102         } else {// edge of volume
    103           off_neg_y = 0;
    104         }
    105       }
    106 
    107       slice = rsGetElementAt_uint(bricks, slice_pos + off_neg_y);
    108       out |= slice;
    109       // + in Y
    110       int off_pos_y = 1;
    111       if (in_br_y == 31) {
    112         if (by < brick_dimy - 1) {
    113           off_pos_y = BRICK_SIZE * brick_dimx - 31;
    114         } else {
    115           off_pos_y = 0;
    116         }
    117       }
    118       slice = rsGetElementAt_uint(bricks, slice_pos + off_pos_y);
    119       out |= slice;
    120       int off_neg_z = -32;
    121       if (in_br_z == 0) {
    122         if (bz > 0) { // edge of screen
    123           off_neg_z = 31*32 - brick_dimx * brick_dimy* BRICK_SIZE;
    124         } else {
    125           off_neg_z = 0;
    126         }
    127       }
    128       slice = rsGetElementAt_uint(bricks, slice_pos + off_neg_z);
    129       out |= slice;
    130       int off_pos_z = 32;
    131       if (in_br_z == 31) {
    132         if (bz < brick_dimz - 1) {
    133           off_pos_z = brick_dimx * brick_dimy * BRICK_SIZE - 31*32;
    134         } else {
    135           off_pos_z = 0;
    136         }
    137       }
    138       slice = rsGetElementAt_uint(bricks, slice_pos + off_pos_z);
    139       out |= slice;
    140 
    141     return out;
    142 
    143 
    144 
    145 }
    146 int z;
    147 
    148 void __attribute__((kernel)) copy(short in, uint32_t x, uint32_t y) {
    149     rsSetElementAt_short(volume, in, x, y, z);
    150 }
    151