Home | History | Annotate | Download | only in refocus
      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 package android.renderscript.cts.refocus;
     18 
     19 
     20 import android.renderscript.Allocation;
     21 import android.renderscript.Element;
     22 import android.renderscript.RenderScript;
     23 
     24 /**
     25  * A class that manages the blur kernel matrices of a blending layer that
     26  * interface between Java and Render Script. This class will be specialized for
     27  * float in f32 package and for byte in u8 package.
     28  *
     29  */
     30 public class KernelDataForRenderScript {
     31     /**
     32      * A flag to turn on using optimized RenderScript.
     33      * False means using original version; true means using the new version.
     34      */
     35     private static boolean UseNewRS = false;
     36 
     37     /**
     38      * Number of sub-pixels that is used to generate anti-aliased blur kernel
     39      * matrix. That is, we divide one pixel into
     40      * {@code NUM_SUB_PIXELS * NUM_SUB_PIXELS} sub-pixels to test whether or not a
     41      * pixel is in the blur disk.
     42      */
     43     protected static final int NUM_SUB_PIXELS = 5;
     44 
     45     /**
     46      * The width of the pixels that are used to pad the image boundary to avoid
     47      * boundary checking in filtering operation.
     48      */
     49     private static final int MAX_KERNEL_RADIUS =
     50             computeKernelRadiusFromDiskRadius(BlurStack.getMaxDiskRadius());
     51 
     52     /**
     53      * The length of an array that concatenates all (vectorized) kernel matrices.
     54      */
     55     protected int stackLength;
     56 
     57     /**
     58      * A class automatically generated by Render Script compiler, which contains
     59      * required auxiliary information to parse {@code kernelStack}, including the
     60      * starting position of each kernel matrix in a memory buffer and the radius
     61      * (radius_x,radius_y) of each kernel matrix. The names radius_x and radius_y
     62      * follow C++ style because render script is C language.
     63      */
     64     protected ScriptField_KernelInfo kernelInfo;
     65 
     66     /**
     67      * Java array version of the current kernel info. Used when UseNewRS is true.
     68      * 4*m: offset; 4*m + 1: radius_x; 4*m + 2: radius_y
     69      */
     70     protected float[] infoArray;
     71 
     72     /**
     73      * An allocation used to store global allocation of stack info. Used when UseNewRS is true.
     74      */
     75     public Allocation infoAllocation;
     76 
     77     public static int getNumSubPixels() {
     78         return NUM_SUB_PIXELS;
     79     }
     80 
     81     public static int getMaxKernelRadius() {
     82         return MAX_KERNEL_RADIUS;
     83     }
     84 
     85     public static void setUseNewRS(boolean choice) {
     86         UseNewRS = choice;
     87     }
     88 
     89     /**
     90      * Computes the kernel matrix radius from the blur disk radius.
     91      *
     92      * @param diskRadius blur disk radius
     93      * @return kernel matrix radius
     94      */
     95     public static int computeKernelRadiusFromDiskRadius(float diskRadius) {
     96         return (int) (diskRadius) + 1;
     97     }
     98 
     99     public ScriptField_KernelInfo getKernelInfo() {
    100         return kernelInfo;
    101     }
    102 
    103     /**
    104      * Initializes {@code kernelInfo}.
    105      *
    106      * @param targetLayer  the index of a target layer
    107      * @param blurStack    an instance of {@code BlurStack}
    108      * @param renderScript an instance of {@code RenderScript}
    109      */
    110     protected KernelDataForRenderScript(int targetLayer, BlurStack blurStack,
    111                                         RenderScript renderScript) {
    112         if (UseNewRS) {
    113             // Use the new version of renderscript files.
    114             int numDepths = blurStack.getNumDepths(targetLayer);
    115             infoAllocation = Allocation.createSized(
    116                     renderScript, Element.F32_4(renderScript),
    117                     numDepths);
    118 
    119             infoArray = new float[4 * numDepths];
    120             // Generates information for each blur kernel matrix.
    121             int offset = 0;
    122             for (int m = 0; m < numDepths; ++m) {
    123                 int depth = blurStack.getDepth(targetLayer, m);
    124                 float diskRadius = blurStack.getDiskRadius(depth);
    125                 int kernelRadius = computeKernelRadiusFromDiskRadius(diskRadius);
    126 
    127                 infoArray[m * 4] = offset;
    128                 infoArray[m * 4 + 1] = kernelRadius;
    129                 infoArray[m * 4 + 2] = kernelRadius;
    130 
    131                 // Updates offset variable.
    132                 int kernelLength = (2 * kernelRadius + 1) * (2 * kernelRadius + 1);
    133                 offset += kernelLength;
    134             }
    135             infoAllocation.copyFrom(infoArray);
    136             stackLength = offset;
    137         } else {
    138             // Use original version of renderscript files.
    139             int numDepths = blurStack.getNumDepths(targetLayer);
    140             kernelInfo = new ScriptField_KernelInfo(renderScript, numDepths);
    141 
    142             // Generates information for each blur kernel matrix.
    143             int offset = 0;
    144             for (int m = 0; m < numDepths; ++m) {
    145                 int depth = blurStack.getDepth(targetLayer, m);
    146                 float diskRadius = blurStack.getDiskRadius(depth);
    147                 int kernelRadius = computeKernelRadiusFromDiskRadius(diskRadius);
    148                 // Sets information for the {@code m}'th kernel matrix.
    149                 kernelInfo.set_offset(m, offset, true);
    150                 kernelInfo.set_radius_x(m, kernelRadius, true);
    151                 kernelInfo.set_radius_y(m, kernelRadius, true);
    152                 // Updates offset variable.
    153                 int kernelLength = (2 * kernelRadius + 1) * (2 * kernelRadius + 1);
    154                 offset += kernelLength;
    155             }
    156             stackLength = offset;
    157         }
    158     }
    159 }
    160