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