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.d1new; 18 19 import android.graphics.Bitmap; 20 import android.renderscript.Allocation; 21 import android.renderscript.RenderScript; 22 23 import android.renderscript.Script; 24 import android.renderscript.cts.refocus.BlurStack; 25 import android.renderscript.cts.refocus.KernelDataForRenderScript; 26 import android.renderscript.cts.refocus.LayerInfo; 27 import android.renderscript.cts.refocus.MediaStoreSaver; 28 import android.renderscript.cts.refocus.RefocusFilter; 29 import android.renderscript.cts.refocus.ScriptC_layered_filter_fast_d1new; 30 import android.util.Log; 31 32 /** 33 * An accelerated implementation of RefocusFilter using float32 as pixel 34 * representation. The corresponding RenderScript class is 35 * ScriptC_layered_filter_Fast. Integral image is used for the speedup. 36 * 37 * Example Usage: 38 * 39 * {@code RenderScript renderScript = RenderScript.create(context);} 40 * {@code RefocusFilterd1new rfFilter = new RefocusFilterd1new(renderScript);} 41 * {@code ProgressCallback progress;} 42 * {@code Bitmap result = rfFilter.compute(rgbdImage, blurStack, progress);} 43 */ 44 public class RefocusFilterd1new extends 45 RefocusFilter<ScriptC_layered_filter_fast_d1new> { 46 private static final String myTAG = "RefocusFilterd1new"; 47 private static final boolean ENABLE_FAST_FILTER = true; 48 private static final float MIN_DISC_RADIUS_FOR_FAST_FILTER = 3; 49 boolean useFastFilterForCurrentLayer = false; 50 ImageBuffersForRenderScriptd1new buffers; 51 Allocation kernelInfo, kernelStack; 52 RefocusFilterd1new(RenderScript rs)53 public RefocusFilterd1new(RenderScript rs) { 54 super(rs); 55 } 56 destroy()57 public void destroy() { 58 buffers.destroy(); 59 kernelInfo.destroy(); 60 kernelStack.destroy(); 61 scriptC.destroy(); 62 } 63 64 @Override initializeScriptAndBuffers(Bitmap inputImage, LayerInfo focalLayer)65 protected void initializeScriptAndBuffers(Bitmap inputImage, 66 LayerInfo focalLayer) { 67 scriptC = new ScriptC_layered_filter_fast_d1new(renderScript); 68 69 // Allocates, binds, and initializes buffers that interface between Java 70 // and Render Script. 71 // + 1 is for the boundary case of using integral image. 72 KernelDataForRenderScript.setUseNewRS(true); 73 int margin = KernelDataForRenderScript.getMaxKernelRadius() + 1; 74 buffers = new ImageBuffersForRenderScriptd1new(inputImage, margin, 75 renderScript, scriptC); 76 buffers.initializeRenderScript(focalLayer, scriptC); 77 } 78 79 @Override extractResultImage()80 protected Bitmap extractResultImage() { 81 // Extracts the result from .rs file to {@code buffers.outputImage} in Java. 82 long startnow; 83 long endnow; 84 startnow = System.nanoTime(); 85 scriptC.forEach_PackOutputImage(buffers.outAllocation); 86 endnow = System.nanoTime(); 87 Log.d(myTAG, "PackOutputImage: "+(endnow - startnow)+ " ns" ); 88 89 buffers.outAllocation.copyTo(buffers.outputImage); 90 return buffers.outputImage; 91 } 92 93 /* 94 * Utility Method to extract intermediatory result 95 */ extractSharpImage(String name)96 private void extractSharpImage(String name) { 97 98 Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), 99 buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); 100 Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); 101 scriptC.forEach_PackSharpImage(mAllocation); 102 103 mAllocation.copyTo(mBitmap); 104 mAllocation.destroy(); 105 MediaStoreSaver.savePNG(mBitmap, "sharpd1new", name, renderScript.getApplicationContext()); 106 } 107 /* 108 * Utility Method to extract intermediatory result 109 */ extractFuzzyImage(String name)110 private void extractFuzzyImage(String name) { 111 112 Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), 113 buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); 114 Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); 115 scriptC.forEach_PackFuzzyImage(mAllocation); 116 117 mAllocation.copyTo(mBitmap); 118 mAllocation.destroy(); 119 MediaStoreSaver.savePNG(mBitmap, "fuzzyd1new", name, renderScript.getApplicationContext()); 120 } 121 122 @Override setTargetLayer(LayerInfo layerInfo)123 protected void setTargetLayer(LayerInfo layerInfo) { 124 scriptC.invoke_SetTargetLayer(layerInfo.frontDepth, layerInfo.backDepth); 125 } 126 127 @Override setBlendInfo(int dilationRadius)128 protected void setBlendInfo(int dilationRadius) { 129 scriptC.invoke_SetBlendInfo(dilationRadius); 130 } 131 132 @Override setKernelData(int targetLayer, BlurStack blurStack)133 protected void setKernelData(int targetLayer, BlurStack blurStack) { 134 KernelDataForRenderScriptd1new kernelData = 135 new KernelDataForRenderScriptd1new(targetLayer, blurStack, renderScript); 136 137 if (ENABLE_FAST_FILTER 138 && kernelData.minDiskRadius > MIN_DISC_RADIUS_FOR_FAST_FILTER) { 139 useFastFilterForCurrentLayer = true; 140 } else { 141 useFastFilterForCurrentLayer = false; 142 } 143 scriptC.set_g_kernel_stack(kernelData.stackAllocation); 144 scriptC.set_galloc_kernel_info(kernelData.infoAllocation); 145 if (kernelInfo != null) { 146 kernelInfo.destroy(); 147 } 148 kernelInfo = kernelData.infoAllocation; 149 if (kernelStack != null) { 150 kernelStack.destroy(); 151 } 152 kernelStack = kernelData.stackAllocation; 153 } 154 155 @Override computeLayerMatteBehindFocalDepth()156 protected void computeLayerMatteBehindFocalDepth() { 157 // Marks active pixels (pixels that are on this target layer); 158 // Marks adjacent pixels that are close enough to active pixels; 159 long startnow; 160 long endnow; 161 162 startnow = System.nanoTime(); 163 //scriptC.forEach_MarkLayerMask(buffers.inAllocation); 164 // Pass the sharp actual depth allocation directly into the kernel, and modify the dilated depth 165 // allocation which is set as a global. 166 scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation); 167 endnow = System.nanoTime(); 168 Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" ); 169 170 startnow = System.nanoTime(); 171 //scriptC.forEach_ComputeLayerMatteBehindFocalDepth(buffers.inAllocation); 172 // Pass g_sharp_meta into kernel and get updated g_sharp_meta 173 scriptC.forEach_ComputeLayerMatteBehindFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 174 endnow = System.nanoTime(); 175 Log.d(myTAG, "ComputeLayerMatteBehindFocalDepth: "+(endnow - startnow)+ " ns" ); 176 } 177 178 @Override filterLayerBehindFocalDepth()179 protected void filterLayerBehindFocalDepth() { 180 // Filters the target layer and saves the result to {@code g_accum_map} in 181 // .rs file. 182 long startnow; 183 long endnow; 184 185 if (useFastFilterForCurrentLayer) { 186 scriptC.invoke_SetUseIntegralImage(1); 187 Script.LaunchOptions launchOptions = new Script.LaunchOptions(); 188 launchOptions.setX(0, 1); 189 launchOptions.setY(0, buffers.inputImage.getHeight()); 190 191 startnow = System.nanoTime(); 192 scriptC.forEach_ComputeIntegralImageForLayerBehindFocalDepth( 193 buffers.inAllocation, launchOptions); 194 endnow = System.nanoTime(); 195 Log.d(myTAG, "ComputeIntegralImageForLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" ); 196 } else { 197 scriptC.invoke_SetUseIntegralImage(0); 198 } 199 200 startnow = System.nanoTime(); 201 //scriptC.forEach_FilterLayerBehindFocalDepth(buffers.inAllocation); 202 // Pass g_fuzzy_RGBA into kernel and get g_fuzzy_RGBA as output 203 scriptC.forEach_FilterLayerBehindFocalDepthPassInput(buffers.fuzzyRGBAAllocation, buffers.fuzzyRGBAAllocation); 204 endnow = System.nanoTime(); 205 Log.d(myTAG, "FilterLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" ); 206 //extractFuzzyImage("fuzzy_behind"); 207 //extractSharpImage("sharp_behind"); 208 } 209 210 @Override updateSharpImageUsingFuzzyImage()211 protected void updateSharpImageUsingFuzzyImage() { 212 long startnow; 213 long endnow; 214 215 startnow = System.nanoTime(); 216 217 //scriptC.forEach_UpdateSharpImageUsingFuzzyImage(buffers.inAllocation); 218 // Pass input and output version of UpdateSharpImageUsingFuzzyImage 219 scriptC.forEach_UpdateSharpUsingFuzzyPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 220 221 endnow = System.nanoTime(); 222 Log.d(myTAG, "updateSharpImageUsingFuzzyImage: "+(endnow - startnow)+ " ns" ); 223 //extractSharpImage("sharp_update"); 224 } 225 226 @Override computeLayerMatteInFrontOfFocalDepth()227 protected void computeLayerMatteInFrontOfFocalDepth() { 228 // Marks active pixels (pixels that are on this target layer); 229 // Marks adjacent pixels that are close enough to active pixels; 230 long startnow; 231 long endnow; 232 233 startnow = System.nanoTime(); 234 //scriptC.forEach_MarkLayerMask(buffers.inAllocation); 235 // Pass the sharp actual depth allocation directly into the kernel, and modify the dilated depth 236 // allocation which is set as a global. 237 scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation); 238 endnow = System.nanoTime(); 239 Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" ); 240 241 startnow = System.nanoTime(); 242 //scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepth(buffers.inAllocation); 243 // Pass g_sharp_meta and g_fuzzy_RGBA directly into the kernel 244 scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 245 endnow = System.nanoTime(); 246 Log.d(myTAG, "ComputeLayerMatteInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); 247 } 248 249 @Override filterLayerInFrontOfFocalDepth()250 protected void filterLayerInFrontOfFocalDepth() { 251 // Filters the target layer and accumulates the result to {@code 252 // g_accum_map} in .rs file. 253 long startnow; 254 long endnow; 255 if (useFastFilterForCurrentLayer) { 256 scriptC.invoke_SetUseIntegralImage(1); 257 Script.LaunchOptions launchOptions = new Script.LaunchOptions(); 258 launchOptions.setX(0, 1); 259 launchOptions.setY(0, buffers.inputImage.getHeight()); 260 261 startnow = System.nanoTime(); 262 scriptC.forEach_ComputeIntegralImageForLayerInFrontOfFocalDepth( 263 buffers.inAllocation, launchOptions); 264 endnow = System.nanoTime(); 265 Log.d(myTAG, "ComputeIntegralImageForLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); 266 } else { 267 scriptC.invoke_SetUseIntegralImage(0); 268 } 269 startnow = System.nanoTime(); 270 //scriptC.forEach_FilterLayerInFrontOfFocalDepth(buffers.inAllocation); 271 // Pass g_sharp_dilated_depth into kernel and get g_fuzzy_RGBA as output 272 scriptC.forEach_FilterLayerInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 273 endnow = System.nanoTime(); 274 Log.d(myTAG, "FilterLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); 275 276 //extractFuzzyImage("fuzzy_front"); 277 //extractSharpImage("sharp_front"); 278 } 279 280 @Override finalizeFuzzyImageUsingSharpImage()281 protected void finalizeFuzzyImageUsingSharpImage() { 282 // Blends {@code g_accum_map} and {@code g_focus_map} in .rs file. 283 // Saves the result in {@code g_accum_map}. 284 long startnow; 285 long endnow; 286 startnow = System.nanoTime(); 287 scriptC.forEach_FinalizeFuzzyImageUsingSharpImage(buffers.inAllocation); 288 //scriptC.forEach_FinalizeFuzzyImageUsingSharpImagePassInput(buffers.sharpActualDepthAllocation, buffers.fuzzyRGBAAllocation); 289 endnow = System.nanoTime(); 290 Log.d(myTAG, "finalizeFuzzyImageUsingSharpImage: "+(endnow - startnow)+ " ns" ); 291 } 292 } 293