summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java')
-rw-r--r--src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java240
1 files changed, 240 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java b/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java
new file mode 100644
index 000000000..1fec62197
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.pipeline;
+
+import android.graphics.Bitmap;
+import android.os.*;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.gallery3d.filtershow.cache.ImageLoader;
+import com.android.gallery3d.filtershow.filters.FiltersManager;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
+
+public class FilteringPipeline implements Handler.Callback {
+
+ private static volatile FilteringPipeline sPipeline = null;
+ private static final String LOGTAG = "FilteringPipeline";
+ private boolean DEBUG = false;
+
+ private static long HIRES_DELAY = 300; // in ms
+
+ private volatile boolean mPipelineIsOn = false;
+
+ private CachingPipeline mAccessoryPipeline = null;
+ private CachingPipeline mPreviewPipeline = null;
+ private CachingPipeline mHighresPreviewPipeline = null;
+
+ private HandlerThread mHandlerThread = null;
+ private final static int NEW_PRESET = 0;
+ private final static int NEW_RENDERING_REQUEST = 1;
+ private final static int COMPUTE_PRESET = 2;
+ private final static int COMPUTE_RENDERING_REQUEST = 3;
+ private final static int COMPUTE_PARTIAL_RENDERING_REQUEST = 4;
+ private final static int COMPUTE_HIGHRES_RENDERING_REQUEST = 5;
+
+ private volatile boolean mHasUnhandledPreviewRequest = false;
+
+ private String getType(int value) {
+ if (value == COMPUTE_RENDERING_REQUEST) {
+ return "COMPUTE_RENDERING_REQUEST";
+ }
+ if (value == COMPUTE_PARTIAL_RENDERING_REQUEST) {
+ return "COMPUTE_PARTIAL_RENDERING_REQUEST";
+ }
+ if (value == COMPUTE_HIGHRES_RENDERING_REQUEST) {
+ return "COMPUTE_HIGHRES_RENDERING_REQUEST";
+ }
+ return "UNKNOWN TYPE";
+ }
+
+ private Handler mProcessingHandler = null;
+ private final Handler mUIHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case NEW_PRESET: {
+ MasterImage.getImage().notifyObservers();
+ if (mHasUnhandledPreviewRequest) {
+ updatePreviewBuffer();
+ }
+ break;
+ }
+ case NEW_RENDERING_REQUEST: {
+ RenderingRequest request = (RenderingRequest) msg.obj;
+ request.markAvailable();
+ break;
+ }
+ }
+ }
+ };
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ if (!mPipelineIsOn) {
+ return false;
+ }
+ switch (msg.what) {
+ case COMPUTE_PRESET: {
+ SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer();
+ SharedPreset preset = MasterImage.getImage().getPreviewPreset();
+ ImagePreset renderingPreset = preset.dequeuePreset();
+ if (renderingPreset != null) {
+ mPreviewPipeline.compute(buffer, renderingPreset, COMPUTE_PRESET);
+ // set the preset we used in the buffer for later inspection UI-side
+ buffer.getProducer().setPreset(renderingPreset);
+ buffer.getProducer().sync();
+ buffer.swapProducer(); // push back the result
+ Message uimsg = mUIHandler.obtainMessage(NEW_PRESET);
+ mUIHandler.sendMessage(uimsg);
+ }
+ break;
+ }
+ case COMPUTE_RENDERING_REQUEST:
+ case COMPUTE_PARTIAL_RENDERING_REQUEST:
+ case COMPUTE_HIGHRES_RENDERING_REQUEST: {
+
+ if (DEBUG) {
+ Log.v(LOGTAG, "Compute Request: " + getType(msg.what));
+ }
+
+ RenderingRequest request = (RenderingRequest) msg.obj;
+ if (msg.what == COMPUTE_HIGHRES_RENDERING_REQUEST) {
+ mHighresPreviewPipeline.render(request);
+ } else {
+ mAccessoryPipeline.render(request);
+ }
+ if (request.getBitmap() != null) {
+ Message uimsg = mUIHandler.obtainMessage(NEW_RENDERING_REQUEST);
+ uimsg.obj = request;
+ mUIHandler.sendMessage(uimsg);
+ }
+ break;
+ }
+ }
+ return false;
+ }
+
+ private FilteringPipeline() {
+ mHandlerThread = new HandlerThread("FilteringPipeline",
+ Process.THREAD_PRIORITY_FOREGROUND);
+ mHandlerThread.start();
+ mProcessingHandler = new Handler(mHandlerThread.getLooper(), this);
+ mAccessoryPipeline = new CachingPipeline(
+ FiltersManager.getManager(), "Accessory");
+ mPreviewPipeline = new CachingPipeline(
+ FiltersManager.getPreviewManager(), "Preview");
+ mHighresPreviewPipeline = new CachingPipeline(
+ FiltersManager.getHighresManager(), "Highres");
+ }
+
+ public synchronized static FilteringPipeline getPipeline() {
+ if (sPipeline == null) {
+ sPipeline = new FilteringPipeline();
+ }
+ return sPipeline;
+ }
+
+ public void setOriginal(Bitmap bitmap) {
+ if (mPipelineIsOn) {
+ Log.e(LOGTAG, "setOriginal called after pipeline initialization!");
+ return;
+ }
+ mAccessoryPipeline.setOriginal(bitmap);
+ mPreviewPipeline.setOriginal(bitmap);
+ mHighresPreviewPipeline.setOriginal(bitmap);
+ }
+
+ public void postRenderingRequest(RenderingRequest request) {
+ if (!mPipelineIsOn) {
+ return;
+ }
+ int type = COMPUTE_RENDERING_REQUEST;
+ if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ type = COMPUTE_PARTIAL_RENDERING_REQUEST;
+ }
+ if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
+ type = COMPUTE_HIGHRES_RENDERING_REQUEST;
+ ImageLoader imageLoader = MasterImage.getImage().getImageLoader();
+ if (imageLoader.getOriginalBitmapHighres() == null) {
+ return;
+ }
+ }
+ Message msg = mProcessingHandler.obtainMessage(type);
+ msg.obj = request;
+ if (type == COMPUTE_PARTIAL_RENDERING_REQUEST
+ || type == COMPUTE_HIGHRES_RENDERING_REQUEST) {
+ if (mProcessingHandler.hasMessages(msg.what)) {
+ mProcessingHandler.removeMessages(msg.what);
+ }
+ mProcessingHandler.sendMessageDelayed(msg, HIRES_DELAY);
+ } else {
+ mProcessingHandler.sendMessage(msg);
+ }
+ }
+
+ public void updatePreviewBuffer() {
+ if (!mPipelineIsOn) {
+ return;
+ }
+ mHasUnhandledPreviewRequest = true;
+ mHighresPreviewPipeline.stop();
+ if (mProcessingHandler.hasMessages(COMPUTE_PRESET)) {
+ return;
+ }
+ if (!mPreviewPipeline.needsRepaint()) {
+ return;
+ }
+ if (MasterImage.getImage().getPreset() == null) {
+ return;
+ }
+ Message msg = mProcessingHandler.obtainMessage(COMPUTE_PRESET);
+ msg.obj = MasterImage.getImage().getPreset();
+ mHasUnhandledPreviewRequest = false;
+ mProcessingHandler.sendMessageAtFrontOfQueue(msg);
+ }
+
+ public void setPreviewScaleFactor(float previewScaleFactor) {
+ mAccessoryPipeline.setPreviewScaleFactor(previewScaleFactor);
+ mPreviewPipeline.setPreviewScaleFactor(previewScaleFactor);
+ mHighresPreviewPipeline.setPreviewScaleFactor(previewScaleFactor);
+ }
+
+ public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) {
+ mAccessoryPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
+ mPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
+ mHighresPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
+ }
+
+ public static synchronized void reset() {
+ sPipeline.mAccessoryPipeline.reset();
+ sPipeline.mPreviewPipeline.reset();
+ sPipeline.mHighresPreviewPipeline.reset();
+ sPipeline.mHandlerThread.quit();
+ sPipeline = null;
+ }
+
+ public void turnOnPipeline(boolean t) {
+ mPipelineIsOn = t;
+ if (mPipelineIsOn) {
+ assert(mPreviewPipeline.isInitialized());
+ assert(mAccessoryPipeline.isInitialized());
+ assert(mHighresPreviewPipeline.isInitialized());
+ updatePreviewBuffer();
+ }
+ }
+}