OSDN Git Service

3232db77476a861d4658b464f7dc0530aeea220a
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / cache / FilteringPipeline.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.os.*;
21 import android.os.Process;
22 import android.support.v8.renderscript.*;
23 import android.util.Log;
24
25 import com.android.gallery3d.filtershow.filters.FiltersManager;
26 import com.android.gallery3d.filtershow.filters.ImageFilterRS;
27 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
28 import com.android.gallery3d.filtershow.imageshow.MasterImage;
29 import com.android.gallery3d.filtershow.pipeline.SharedBuffer;
30 import com.android.gallery3d.filtershow.pipeline.SharedPreset;
31 import com.android.gallery3d.filtershow.presets.ImagePreset;
32
33 public class FilteringPipeline implements Handler.Callback {
34
35     private static volatile FilteringPipeline sPipeline = null;
36     private static final String LOGTAG = "FilteringPipeline";
37     private boolean DEBUG = false;
38
39     private static long HIRES_DELAY = 300; // in ms
40
41     private volatile boolean mPipelineIsOn = false;
42
43     private CachingPipeline mAccessoryPipeline = null;
44     private CachingPipeline mPreviewPipeline = null;
45     private CachingPipeline mHighresPreviewPipeline = null;
46
47     private HandlerThread mHandlerThread = null;
48     private final static int NEW_PRESET = 0;
49     private final static int NEW_RENDERING_REQUEST = 1;
50     private final static int COMPUTE_PRESET = 2;
51     private final static int COMPUTE_RENDERING_REQUEST = 3;
52     private final static int COMPUTE_PARTIAL_RENDERING_REQUEST = 4;
53     private final static int COMPUTE_HIGHRES_RENDERING_REQUEST = 5;
54
55     private volatile boolean mHasUnhandledPreviewRequest = false;
56
57     private String getType(int value) {
58         if (value == COMPUTE_RENDERING_REQUEST) {
59             return "COMPUTE_RENDERING_REQUEST";
60         }
61         if (value == COMPUTE_PARTIAL_RENDERING_REQUEST) {
62             return "COMPUTE_PARTIAL_RENDERING_REQUEST";
63         }
64         if (value == COMPUTE_HIGHRES_RENDERING_REQUEST) {
65             return "COMPUTE_HIGHRES_RENDERING_REQUEST";
66         }
67         return "UNKNOWN TYPE";
68     }
69
70     private Handler mProcessingHandler = null;
71     private final Handler mUIHandler = new Handler() {
72         @Override
73         public void handleMessage(Message msg) {
74             switch (msg.what) {
75                 case NEW_PRESET: {
76                     MasterImage.getImage().notifyObservers();
77                     if (mHasUnhandledPreviewRequest) {
78                         updatePreviewBuffer();
79                     }
80                     break;
81                 }
82                 case NEW_RENDERING_REQUEST: {
83                     RenderingRequest request = (RenderingRequest) msg.obj;
84                     request.markAvailable();
85                     break;
86                 }
87             }
88         }
89     };
90
91     @Override
92     public boolean handleMessage(Message msg) {
93         if (!mPipelineIsOn) {
94             return false;
95         }
96         switch (msg.what) {
97             case COMPUTE_PRESET: {
98                 SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer();
99                 SharedPreset preset = MasterImage.getImage().getPreviewPreset();
100                 ImagePreset renderingPreset = preset.dequeuePreset();
101                 if (renderingPreset != null) {
102                     mPreviewPipeline.compute(buffer, renderingPreset, COMPUTE_PRESET);
103                     // set the preset we used in the buffer for later inspection UI-side
104                     buffer.getProducer().setPreset(renderingPreset);
105                     buffer.getProducer().sync();
106                     buffer.swapProducer(); // push back the result
107                     Message uimsg = mUIHandler.obtainMessage(NEW_PRESET);
108                     mUIHandler.sendMessage(uimsg);
109                 }
110                 break;
111             }
112             case COMPUTE_RENDERING_REQUEST:
113             case COMPUTE_PARTIAL_RENDERING_REQUEST:
114             case COMPUTE_HIGHRES_RENDERING_REQUEST: {
115
116                 if (DEBUG) {
117                     Log.v(LOGTAG, "Compute Request: " + getType(msg.what));
118                 }
119
120                 RenderingRequest request = (RenderingRequest) msg.obj;
121                 if (msg.what == COMPUTE_HIGHRES_RENDERING_REQUEST) {
122                     mHighresPreviewPipeline.render(request);
123                 } else {
124                     mAccessoryPipeline.render(request);
125                 }
126                 if (request.getBitmap() != null) {
127                     Message uimsg = mUIHandler.obtainMessage(NEW_RENDERING_REQUEST);
128                     uimsg.obj = request;
129                     mUIHandler.sendMessage(uimsg);
130                 }
131                 break;
132             }
133         }
134         return false;
135     }
136
137     private FilteringPipeline() {
138         mHandlerThread = new HandlerThread("FilteringPipeline",
139                 Process.THREAD_PRIORITY_FOREGROUND);
140         mHandlerThread.start();
141         mProcessingHandler = new Handler(mHandlerThread.getLooper(), this);
142         mAccessoryPipeline = new CachingPipeline(
143                 FiltersManager.getManager(), "Accessory");
144         mPreviewPipeline = new CachingPipeline(
145                 FiltersManager.getPreviewManager(), "Preview");
146         mHighresPreviewPipeline = new CachingPipeline(
147                 FiltersManager.getHighresManager(), "Highres");
148     }
149
150     public synchronized static FilteringPipeline getPipeline() {
151         if (sPipeline == null) {
152             sPipeline = new FilteringPipeline();
153         }
154         return sPipeline;
155     }
156
157     public void setOriginal(Bitmap bitmap) {
158         if (mPipelineIsOn) {
159             Log.e(LOGTAG, "setOriginal called after pipeline initialization!");
160             return;
161         }
162         mAccessoryPipeline.setOriginal(bitmap);
163         mPreviewPipeline.setOriginal(bitmap);
164         mHighresPreviewPipeline.setOriginal(bitmap);
165     }
166
167     public void postRenderingRequest(RenderingRequest request) {
168         if (!mPipelineIsOn) {
169             return;
170         }
171         int type = COMPUTE_RENDERING_REQUEST;
172         if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
173             type = COMPUTE_PARTIAL_RENDERING_REQUEST;
174         }
175         if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
176             type = COMPUTE_HIGHRES_RENDERING_REQUEST;
177             ImageLoader imageLoader = MasterImage.getImage().getImageLoader();
178             if (imageLoader.getOriginalBitmapHighres() == null) {
179                 return;
180             }
181         }
182         Message msg = mProcessingHandler.obtainMessage(type);
183         msg.obj = request;
184         if (type == COMPUTE_PARTIAL_RENDERING_REQUEST
185                 || type == COMPUTE_HIGHRES_RENDERING_REQUEST) {
186             if (mProcessingHandler.hasMessages(msg.what)) {
187                 mProcessingHandler.removeMessages(msg.what);
188             }
189             mProcessingHandler.sendMessageDelayed(msg, HIRES_DELAY);
190         } else {
191             mProcessingHandler.sendMessage(msg);
192         }
193     }
194
195     public void updatePreviewBuffer() {
196         if (!mPipelineIsOn) {
197             return;
198         }
199         mHasUnhandledPreviewRequest = true;
200         mHighresPreviewPipeline.stop();
201         if (mProcessingHandler.hasMessages(COMPUTE_PRESET)) {
202             return;
203         }
204         if (!mPreviewPipeline.needsRepaint()) {
205             return;
206         }
207         if (MasterImage.getImage().getPreset() == null) {
208             return;
209         }
210         Message msg = mProcessingHandler.obtainMessage(COMPUTE_PRESET);
211         msg.obj = MasterImage.getImage().getPreset();
212         mHasUnhandledPreviewRequest = false;
213         mProcessingHandler.sendMessageAtFrontOfQueue(msg);
214     }
215
216     public void setPreviewScaleFactor(float previewScaleFactor) {
217         mAccessoryPipeline.setPreviewScaleFactor(previewScaleFactor);
218         mPreviewPipeline.setPreviewScaleFactor(previewScaleFactor);
219         mHighresPreviewPipeline.setPreviewScaleFactor(previewScaleFactor);
220     }
221
222     public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) {
223         mAccessoryPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
224         mPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
225         mHighresPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
226     }
227
228     public static synchronized void reset() {
229         sPipeline.mAccessoryPipeline.reset();
230         sPipeline.mPreviewPipeline.reset();
231         sPipeline.mHighresPreviewPipeline.reset();
232         sPipeline.mHandlerThread.quit();
233         sPipeline = null;
234     }
235
236     public void turnOnPipeline(boolean t) {
237         mPipelineIsOn = t;
238         if (mPipelineIsOn) {
239             assert(mPreviewPipeline.isInitialized());
240             assert(mAccessoryPipeline.isInitialized());
241             assert(mHighresPreviewPipeline.isInitialized());
242             updatePreviewBuffer();
243         }
244     }
245 }