1 #ifndef LUTS_FOR_SPEEDUP_F32_RSH 2 #define LUTS_FOR_SPEEDUP_F32_RSH 3 4 // Defines several LUTs for speed up for uint8 pixel type. 5 6 // Depth Range: [1,g_kMaxDepthValue]; 0 is reserved for invalid pixels. 7 // g_kMaxDepthValue must be the same as BlurStack::MAX_DEPTH. 8 static const int g_kMaxDepthValue = 64; 9 10 // A lookup table that heuristically computes the probability that a layer with 11 // depth y is visible in the presence of a pixel with depth x. 12 // VisibilityProbability.lut[y][x] = 1.0f/(max(x-y,0)+1). 13 // The value range of both x and y is [0,g_kMaxDepthValue]. 14 // The value range of VisibilityProbability.lut[y][x] is [0,1]. 15 typedef struct VisibilityProbability { 16 float lut[g_kMaxDepthValue + 1][g_kMaxDepthValue + 1]; 17 } VisibilityProbability_t; 18 19 // Assumes a <= b. 20 // When a = b, RemoveInterval(x,a,b) always returns x. 21 // When a < b, 22 // if x <= a, RemoveInterval(x,a,b) = x; 23 // if a < x <= b, RemoveInterval(x,a,b) = a; 24 // if b < x, RemoveInterval(x,a,b) = a + (x-b). 25 static inline int RemoveInterval(int x, int a, int b) { 26 return (x <= a) ? (x) : (a + max(x - b, 0)); 27 } 28 29 static inline void InitializeVisibilityProbability( 30 VisibilityProbability_t* visibility_probability, int front_focal_depth, 31 int back_focal_depth) { 32 // We expect back_focal_depth <= front_focal_depth. 33 for (int y = 0; y <= g_kMaxDepthValue; y++) { 34 for (int x = 0; x <= g_kMaxDepthValue; x++) { 35 if (y == 0 || x == 0) { 36 visibility_probability->lut[y][x] = 0; 37 } else if (y <= back_focal_depth) { 38 const int z = RemoveInterval(x, back_focal_depth, front_focal_depth); 39 visibility_probability->lut[y][x] = 1.0f / (max(z - y, 0) + 1); 40 } else if (y <= front_focal_depth) { 41 // For a depth value within the focal layer, only depth values in front 42 // of the focal layer are considered as its potential occluders. That 43 // is, a depth value x that has a larger value (closer to the camera) 44 // than y but is still within the focal layer is _not_ considered as an 45 // occluder to y. 46 visibility_probability->lut[y][x] = 47 1.0f / (max(x - front_focal_depth, 0) + 1); 48 } else { 49 // For depths > front_focal_depth, visibility check is not used in 50 // filtering. So always sets it to 1. 51 visibility_probability->lut[y][x] = 1; 52 } 53 } 54 } 55 } 56 57 // g_kMaxKernelRadius must match the value returned by 58 // KernelDataForRenderScript.computeKernelRadiusFromDiskRadius( 59 // BlurStack::MaxDiscRadius). 60 static const int g_kMaxKernelRadius = 25 + 1; 61 62 // A lookup table that pre-computes x coordinate of the intersection between a 63 // circle of radius r and a horizontal line of height y. 64 // lut[r][y+g_kMaxKernelRadius] = x; 65 // The value range of r is [0,g_kMaxKernelRadius]. 66 // The value range of y is [-g_kMaxKernelRadius,g_kMaxKernelRadius]. 67 typedef struct SecantOffset { 68 int lut[g_kMaxKernelRadius + 1][2 * g_kMaxKernelRadius + 1]; 69 } SecantOffset_t; 70 71 static inline void InitializeRadiusOffset(SecantOffset_t* secant_offset) { 72 for (int r = 0; r <= g_kMaxKernelRadius; ++r) { 73 for (int y = -g_kMaxKernelRadius; y <= g_kMaxKernelRadius; ++y) { 74 float tmp = max(0, r * r - y * y); 75 secant_offset->lut[r][y + g_kMaxKernelRadius] = 76 (int)round(half_sqrt(tmp)); 77 } 78 } 79 } 80 81 #endif