Home | History | Annotate | Download | only in test
      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