OSDN Git Service

am 202ad881: am 5842f8e9: am 18027792: Fix problem applying the Fx filter Also adds...
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / cache / CachingPipeline.java
1 /*
2  * Copyright (C) 2013 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 com.android.gallery3d.filtershow.cache;
18
19 import android.graphics.Bitmap;
20 import android.support.v8.renderscript.Allocation;
21 import android.support.v8.renderscript.RenderScript;
22 import android.util.Log;
23 import com.android.gallery3d.filtershow.filters.FiltersManager;
24 import com.android.gallery3d.filtershow.filters.ImageFilterRS;
25 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
26 import com.android.gallery3d.filtershow.imageshow.MasterImage;
27 import com.android.gallery3d.filtershow.presets.ImagePreset;
28
29 public class CachingPipeline {
30     private static final String LOGTAG = "CachingPipeline";
31     private boolean DEBUG = false;
32
33     private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
34
35     private FiltersManager mFiltersManager = null;
36     private volatile Bitmap mOriginalBitmap = null;
37     private volatile Bitmap mResizedOriginalBitmap = null;
38
39     private volatile Allocation mOriginalAllocation = null;
40     private volatile Allocation mFiltersOnlyOriginalAllocation =  null;
41
42     protected volatile Allocation mInPixelsAllocation;
43     protected volatile Allocation mOutPixelsAllocation;
44     private volatile int mWidth = 0;
45     private volatile int mHeight = 0;
46
47     private volatile GeometryMetadata mPreviousGeometry = null;
48     private volatile float mPreviewScaleFactor = 1.0f;
49     private volatile String mName = "";
50
51     public CachingPipeline(FiltersManager filtersManager, String name) {
52         mFiltersManager = filtersManager;
53         mName = name;
54     }
55
56     public synchronized void reset() {
57         mOriginalBitmap = null; // just a reference to the bitmap in ImageLoader
58         if (mResizedOriginalBitmap != null) {
59             mResizedOriginalBitmap.recycle();
60             mResizedOriginalBitmap = null;
61         }
62         if (mOriginalAllocation != null) {
63             mOriginalAllocation.destroy();
64             mOriginalAllocation = null;
65         }
66         if (mFiltersOnlyOriginalAllocation != null) {
67             mFiltersOnlyOriginalAllocation.destroy();
68             mFiltersOnlyOriginalAllocation = null;
69         }
70         mPreviousGeometry = null;
71         mPreviewScaleFactor = 1.0f;
72
73         destroyPixelAllocations();
74     }
75
76     private synchronized void destroyPixelAllocations() {
77         if (DEBUG) {
78             Log.v(LOGTAG, "destroyPixelAllocations in " + getName());
79         }
80         if (mInPixelsAllocation != null) {
81             mInPixelsAllocation.destroy();
82             mInPixelsAllocation = null;
83         }
84         if (mOutPixelsAllocation != null) {
85             mOutPixelsAllocation.destroy();
86             mOutPixelsAllocation = null;
87         }
88         mWidth = 0;
89         mHeight = 0;
90     }
91
92     private String getType(RenderingRequest request) {
93         if (request.getType() == RenderingRequest.ICON_RENDERING) {
94             return "ICON_RENDERING";
95         }
96         if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
97             return "FILTERS_RENDERING";
98         }
99         if (request.getType() == RenderingRequest.FULL_RENDERING) {
100             return "FULL_RENDERING";
101         }
102         if (request.getType() == RenderingRequest.GEOMETRY_RENDERING) {
103             return "GEOMETRY_RENDERING";
104         }
105         if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
106             return "PARTIAL_RENDERING";
107         }
108         return "UNKNOWN TYPE!";
109     }
110
111     private void setPresetParameters(ImagePreset preset) {
112         preset.setScaleFactor(mPreviewScaleFactor);
113         preset.setQuality(ImagePreset.QUALITY_PREVIEW);
114         preset.setupEnvironment(mFiltersManager);
115         preset.getEnvironment().setCachingPipeline(this);
116     }
117
118     public void setOriginal(Bitmap bitmap) {
119         mOriginalBitmap = bitmap;
120         Log.v(LOGTAG,"setOriginal, size " + bitmap.getWidth() + " x " + bitmap.getHeight());
121         ImagePreset preset = MasterImage.getImage().getPreset();
122         preset.setupEnvironment(mFiltersManager);
123         updateOriginalAllocation(preset);
124     }
125
126     private synchronized boolean updateOriginalAllocation(ImagePreset preset) {
127         Bitmap originalBitmap = mOriginalBitmap;
128
129         if (originalBitmap == null) {
130             return false;
131         }
132
133         GeometryMetadata geometry = preset.getGeometry();
134         if (mPreviousGeometry != null && geometry.equals(mPreviousGeometry)) {
135             return false;
136         }
137
138         if (DEBUG) {
139             Log.v(LOGTAG, "geometry has changed");
140         }
141
142         RenderScript RS = ImageFilterRS.getRenderScriptContext();
143
144         Allocation filtersOnlyOriginalAllocation = mFiltersOnlyOriginalAllocation;
145         mFiltersOnlyOriginalAllocation = Allocation.createFromBitmap(RS, originalBitmap,
146                 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
147         if (filtersOnlyOriginalAllocation != null) {
148             filtersOnlyOriginalAllocation.destroy();
149         }
150
151         Allocation originalAllocation = mOriginalAllocation;
152         mResizedOriginalBitmap = preset.applyGeometry(originalBitmap);
153         mOriginalAllocation = Allocation.createFromBitmap(RS, mResizedOriginalBitmap,
154                 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
155         if (originalAllocation != null) {
156             originalAllocation.destroy();
157         }
158
159         mPreviousGeometry = new GeometryMetadata(geometry);
160         return true;
161     }
162
163     public synchronized void render(RenderingRequest request) {
164         if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
165                 && request.getBitmap() == null)
166                 || request.getImagePreset() == null) {
167             return;
168         }
169
170         if (DEBUG) {
171             Log.v(LOGTAG, "render image of type " + getType(request));
172         }
173
174         Bitmap bitmap = request.getBitmap();
175         ImagePreset preset = request.getImagePreset();
176         setPresetParameters(preset);
177         mFiltersManager.freeFilterResources(preset);
178
179         if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
180             ImageLoader loader = MasterImage.getImage().getImageLoader();
181             if (loader == null) {
182                 Log.w(LOGTAG, "loader not yet setup, cannot handle: " + getType(request));
183                 return;
184             }
185             bitmap = loader.getScaleOneImageForPreset(null, preset,
186                     request.getBounds(), request.getDestination(), false);
187             if (bitmap == null) {
188                 Log.w(LOGTAG, "could not get bitmap for: " + getType(request));
189                 return;
190             }
191         }
192
193         if (request.getType() == RenderingRequest.FULL_RENDERING
194                 || request.getType() == RenderingRequest.GEOMETRY_RENDERING
195                 || request.getType() == RenderingRequest.FILTERS_RENDERING) {
196             updateOriginalAllocation(preset);
197         }
198
199         if (DEBUG) {
200             Log.v(LOGTAG, "after update, req bitmap (" + bitmap.getWidth() + "x" + bitmap.getHeight()
201                     +" ? resizeOriginal (" + mResizedOriginalBitmap.getWidth() + "x"
202                     + mResizedOriginalBitmap.getHeight());
203         }
204
205         if (request.getType() == RenderingRequest.FULL_RENDERING
206                 || request.getType() == RenderingRequest.GEOMETRY_RENDERING) {
207             mOriginalAllocation.copyTo(bitmap);
208         } else if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
209             mFiltersOnlyOriginalAllocation.copyTo(bitmap);
210         }
211
212         if (request.getType() == RenderingRequest.FULL_RENDERING
213                 || request.getType() == RenderingRequest.FILTERS_RENDERING
214                 || request.getType() == RenderingRequest.ICON_RENDERING
215                 || request.getType() == RenderingRequest.PARTIAL_RENDERING) {
216             Bitmap bmp = preset.apply(bitmap);
217             request.setBitmap(bmp);
218             mFiltersManager.freeFilterResources(preset);
219         }
220
221     }
222
223     public synchronized Bitmap renderFinalImage(Bitmap bitmap, ImagePreset preset) {
224         setPresetParameters(preset);
225         mFiltersManager.freeFilterResources(preset);
226         bitmap = preset.applyGeometry(bitmap);
227         bitmap = preset.apply(bitmap);
228         return bitmap;
229     }
230
231     public synchronized void compute(TripleBufferBitmap buffer, ImagePreset preset, int type) {
232         if (DEBUG) {
233             Log.v(LOGTAG, "compute preset " + preset);
234             preset.showFilters();
235         }
236
237         String thread = Thread.currentThread().getName();
238         long time = System.currentTimeMillis();
239         setPresetParameters(preset);
240         mFiltersManager.freeFilterResources(preset);
241
242         Bitmap resizedOriginalBitmap = mResizedOriginalBitmap;
243         if (updateOriginalAllocation(preset)) {
244             resizedOriginalBitmap = mResizedOriginalBitmap;
245             buffer.updateBitmaps(resizedOriginalBitmap);
246         }
247         Bitmap bitmap = buffer.getProducer();
248         long time2 = System.currentTimeMillis();
249
250         if (bitmap == null || (bitmap.getWidth() != resizedOriginalBitmap.getWidth())
251                 || (bitmap.getHeight() != resizedOriginalBitmap.getHeight())) {
252             buffer.updateBitmaps(resizedOriginalBitmap);
253             bitmap = buffer.getProducer();
254         }
255         mOriginalAllocation.copyTo(bitmap);
256
257         bitmap = preset.apply(bitmap);
258
259         mFiltersManager.freeFilterResources(preset);
260
261         time = System.currentTimeMillis() - time;
262         time2 = System.currentTimeMillis() - time2;
263         if (DEBUG) {
264             Log.v(LOGTAG, "Applying type " + type + " filters to bitmap "
265                     + bitmap + " (" + bitmap.getWidth() + " x " + bitmap.getHeight()
266                     + ") took " + time + " ms, " + time2 + " ms for the filter, on thread " + thread);
267         }
268     }
269
270     public boolean needsRepaint() {
271         TripleBufferBitmap buffer = MasterImage.getImage().getDoubleBuffer();
272         return buffer.checkRepaintNeeded();
273     }
274
275
276     public void setPreviewScaleFactor(float previewScaleFactor) {
277         mPreviewScaleFactor = previewScaleFactor;
278     }
279
280     public synchronized boolean isInitialized() {
281         return mOriginalBitmap != null;
282     }
283
284     public boolean prepareRenderscriptAllocations(Bitmap bitmap) {
285         RenderScript RS = ImageFilterRS.getRenderScriptContext();
286         boolean needsUpdate = false;
287         if (mOutPixelsAllocation == null || mInPixelsAllocation == null ||
288                 bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight) {
289             destroyPixelAllocations();
290             Bitmap bitmapBuffer = bitmap;
291             if (bitmap.getConfig() == null || bitmap.getConfig() != BITMAP_CONFIG) {
292                 bitmapBuffer = bitmap.copy(BITMAP_CONFIG, true);
293             }
294             mOutPixelsAllocation = Allocation.createFromBitmap(RS, bitmapBuffer,
295                     Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
296             mInPixelsAllocation = Allocation.createTyped(RS,
297                     mOutPixelsAllocation.getType());
298             needsUpdate = true;
299         }
300         mInPixelsAllocation.copyFrom(bitmap);
301         if (bitmap.getWidth() != mWidth
302                 || bitmap.getHeight() != mHeight) {
303             mWidth = bitmap.getWidth();
304             mHeight = bitmap.getHeight();
305             needsUpdate = true;
306         }
307         if (DEBUG) {
308             Log.v(LOGTAG, "prepareRenderscriptAllocations: " + needsUpdate + " in " + getName());
309         }
310         return needsUpdate;
311     }
312
313     public synchronized Allocation getInPixelsAllocation() {
314         return mInPixelsAllocation;
315     }
316
317     public synchronized Allocation getOutPixelsAllocation() {
318         return mOutPixelsAllocation;
319     }
320
321     public String getName() {
322         return mName;
323     }
324 }