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 getNumSubPixels()77 public static int getNumSubPixels() { 78 return NUM_SUB_PIXELS; 79 } 80 getMaxKernelRadius()81 public static int getMaxKernelRadius() { 82 return MAX_KERNEL_RADIUS; 83 } 84 setUseNewRS(boolean choice)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 */ computeKernelRadiusFromDiskRadius(float diskRadius)95 public static int computeKernelRadiusFromDiskRadius(float diskRadius) { 96 return (int) (diskRadius) + 1; 97 } 98 getKernelInfo()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 */ KernelDataForRenderScript(int targetLayer, BlurStack blurStack, RenderScript renderScript)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