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 21int brick_dimx; 22int brick_dimy; 23int brick_dimz; 24rs_allocation volume; 25rs_allocation opacity; 26int z_offset; 27// output a single bit per pixel volume based on opacity 28 29uint __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} 64rs_allocation bricks; // input bricks 65 66uint __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} 146int z; 147 148void __attribute__((kernel)) copy(short in, uint32_t x, uint32_t y) { 149 rsSetElementAt_short(volume, in, x, y, z); 150} 151