Merge "Implements progressive rendering" into gb-ub-photos-bryce
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index 90ef74e..8c5d7a4 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -96,6 +96,8 @@
private String mAction = "";
MasterImage mMasterImage = null;
+ private static final long LIMIT_SUPPORTS_HIGHRES = 134217728; // 128Mb
+
public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET";
public static final String LAUNCH_FULLSCREEN = "launch-fullscreen";
public static final int MAX_BMAP_IN_INTENT = 990000;
@@ -489,7 +491,11 @@
pipeline.setOriginal(largeBitmap);
float previewScale = (float) largeBitmap.getWidth() / (float) mImageLoader.getOriginalBounds().width();
pipeline.setPreviewScaleFactor(previewScale);
-
+ Bitmap highresBitmap = mImageLoader.getOriginalBitmapHighres();
+ if (highresBitmap != null) {
+ float highResPreviewScale = (float) highresBitmap.getWidth() / (float) mImageLoader.getOriginalBounds().width();
+ pipeline.setHighResPreviewScaleFactor(highResPreviewScale);
+ }
pipeline.turnOnPipeline(true);
MasterImage.getImage().setOriginalGeometry(largeBitmap);
mLoadBitmapTask = null;
@@ -881,6 +887,12 @@
mMasterImage.setStateAdapter(mImageStateAdapter);
mMasterImage.setActivity(this);
mMasterImage.setImageLoader(mImageLoader);
+
+ if (Runtime.getRuntime().maxMemory() > LIMIT_SUPPORTS_HIGHRES) {
+ mMasterImage.setSupportsHighRes(true);
+ } else {
+ mMasterImage.setSupportsHighRes(false);
+ }
}
// //////////////////////////////////////////////////////////////////////////////
diff --git a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
index bc1d450..ecfdaba 100644
--- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
+++ b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
@@ -54,6 +54,7 @@
private volatile GeometryMetadata mPreviousGeometry = null;
private volatile float mPreviewScaleFactor = 1.0f;
+ private volatile float mHighResPreviewScaleFactor = 1.0f;
private volatile String mName = "";
public CachingPipeline(FiltersManager filtersManager, String name) {
@@ -112,6 +113,7 @@
}
mPreviousGeometry = null;
mPreviewScaleFactor = 1.0f;
+ mHighResPreviewScaleFactor = 1.0f;
destroyPixelAllocations();
}
@@ -149,13 +151,20 @@
if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
return "PARTIAL_RENDERING";
}
+ if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
+ return "HIGHRES_RENDERING";
+ }
return "UNKNOWN TYPE!";
}
- private void setupEnvironment(ImagePreset preset) {
+ private void setupEnvironment(ImagePreset preset, boolean highResPreview) {
mEnvironment.setCachingPipeline(this);
mEnvironment.setFiltersManager(mFiltersManager);
- mEnvironment.setScaleFactor(mPreviewScaleFactor);
+ if (highResPreview) {
+ mEnvironment.setScaleFactor(mHighResPreviewScaleFactor);
+ } else {
+ mEnvironment.setScaleFactor(mPreviewScaleFactor);
+ }
mEnvironment.setQuality(ImagePreset.QUALITY_PREVIEW);
mEnvironment.setImagePreset(preset);
}
@@ -164,7 +173,7 @@
mOriginalBitmap = bitmap;
Log.v(LOGTAG,"setOriginal, size " + bitmap.getWidth() + " x " + bitmap.getHeight());
ImagePreset preset = MasterImage.getImage().getPreset();
- setupEnvironment(preset);
+ setupEnvironment(preset, false);
updateOriginalAllocation(preset);
}
@@ -210,7 +219,8 @@
if (getRenderScriptContext() == null) {
return;
}
- if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
+ if (((request.getType() != RenderingRequest.PARTIAL_RENDERING
+ && request.getType() != RenderingRequest.HIGHRES_RENDERING)
&& request.getBitmap() == null)
|| request.getImagePreset() == null) {
return;
@@ -222,7 +232,8 @@
Bitmap bitmap = request.getBitmap();
ImagePreset preset = request.getImagePreset();
- setupEnvironment(preset);
+ setupEnvironment(preset,
+ request.getType() != RenderingRequest.HIGHRES_RENDERING);
mFiltersManager.freeFilterResources(preset);
if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
@@ -239,6 +250,12 @@
}
}
+ if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
+ ImageLoader loader = MasterImage.getImage().getImageLoader();
+ bitmap = loader.getOriginalBitmapHighres();
+ bitmap = preset.applyGeometry(bitmap, mEnvironment);
+ }
+
if (request.getType() == RenderingRequest.FULL_RENDERING
|| request.getType() == RenderingRequest.GEOMETRY_RENDERING
|| request.getType() == RenderingRequest.FILTERS_RENDERING) {
@@ -261,7 +278,8 @@
if (request.getType() == RenderingRequest.FULL_RENDERING
|| request.getType() == RenderingRequest.FILTERS_RENDERING
|| request.getType() == RenderingRequest.ICON_RENDERING
- || request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ || request.getType() == RenderingRequest.PARTIAL_RENDERING
+ || request.getType() == RenderingRequest.HIGHRES_RENDERING) {
Bitmap bmp = preset.apply(bitmap, mEnvironment);
request.setBitmap(bmp);
mFiltersManager.freeFilterResources(preset);
@@ -274,7 +292,7 @@
if (getRenderScriptContext() == null) {
return bitmap;
}
- setupEnvironment(preset);
+ setupEnvironment(preset, false);
mEnvironment.setQuality(ImagePreset.QUALITY_FINAL);
mEnvironment.setScaleFactor(1.0f);
mFiltersManager.freeFilterResources(preset);
@@ -289,7 +307,7 @@
if (getRenderScriptContext() == null) {
return bitmap;
}
- setupEnvironment(preset);
+ setupEnvironment(preset, false);
mEnvironment.setQuality(ImagePreset.QUALITY_PREVIEW);
mFiltersManager.freeFilterResources(preset);
bitmap = preset.applyGeometry(bitmap, mEnvironment);
@@ -309,7 +327,7 @@
String thread = Thread.currentThread().getName();
long time = System.currentTimeMillis();
- setupEnvironment(preset);
+ setupEnvironment(preset, false);
mFiltersManager.freeFilterResources(preset);
Bitmap resizedOriginalBitmap = mResizedOriginalBitmap;
@@ -346,11 +364,14 @@
return buffer.checkRepaintNeeded();
}
-
public void setPreviewScaleFactor(float previewScaleFactor) {
mPreviewScaleFactor = previewScaleFactor;
}
+ public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) {
+ mHighResPreviewScaleFactor = highResPreviewScaleFactor;
+ }
+
public synchronized boolean isInitialized() {
return getRenderScriptContext() != null && mOriginalBitmap != null;
}
diff --git a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
index 1ba6e95..ce66b5b 100644
--- a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
+++ b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
@@ -47,9 +47,23 @@
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
@@ -89,12 +103,19 @@
break;
}
case COMPUTE_RENDERING_REQUEST:
- case COMPUTE_PARTIAL_RENDERING_REQUEST: {
- if (msg.what == COMPUTE_PARTIAL_RENDERING_REQUEST) {
- if (mProcessingHandler.hasMessages(COMPUTE_PARTIAL_RENDERING_REQUEST)) {
+ case COMPUTE_PARTIAL_RENDERING_REQUEST:
+ case COMPUTE_HIGHRES_RENDERING_REQUEST: {
+ if (msg.what == COMPUTE_PARTIAL_RENDERING_REQUEST
+ || msg.what == COMPUTE_HIGHRES_RENDERING_REQUEST) {
+ if (mProcessingHandler.hasMessages(msg.what)) {
return false;
}
}
+
+ if (DEBUG) {
+ Log.v(LOGTAG, "Compute Request: " + getType(msg.what));
+ }
+
RenderingRequest request = (RenderingRequest) msg.obj;
mAccessoryPipeline.render(request);
Message uimsg = mUIHandler.obtainMessage(NEW_RENDERING_REQUEST);
@@ -140,9 +161,13 @@
if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
type = COMPUTE_PARTIAL_RENDERING_REQUEST;
}
+ if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
+ type = COMPUTE_HIGHRES_RENDERING_REQUEST;
+ }
Message msg = mProcessingHandler.obtainMessage(type);
msg.obj = request;
- if (type == COMPUTE_PARTIAL_RENDERING_REQUEST) {
+ if (type == COMPUTE_PARTIAL_RENDERING_REQUEST
+ || type == COMPUTE_HIGHRES_RENDERING_REQUEST) {
mProcessingHandler.sendMessageDelayed(msg, HIRES_DELAY);
} else {
mProcessingHandler.sendMessage(msg);
@@ -174,6 +199,11 @@
mPreviewPipeline.setPreviewScaleFactor(previewScaleFactor);
}
+ public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) {
+ mAccessoryPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
+ mPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor);
+ }
+
public static synchronized void reset() {
sPipeline.mAccessoryPipeline.reset();
sPipeline.mPreviewPipeline.reset();
diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
index a6a0bcf..b4e98e1 100644
--- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
+++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
@@ -42,6 +42,7 @@
import com.android.gallery3d.filtershow.HistoryAdapter;
import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.imageshow.ImageShow;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
import com.android.gallery3d.filtershow.tools.BitmapTask;
import com.android.gallery3d.filtershow.tools.SaveCopyTask;
@@ -67,6 +68,7 @@
private final Vector<ImageShow> mListeners = new Vector<ImageShow>();
private Bitmap mOriginalBitmapSmall = null;
private Bitmap mOriginalBitmapLarge = null;
+ private Bitmap mOriginalBitmapHighres = null;
private Bitmap mBackgroundBitmap = null;
private final ZoomCache mZoomCache = new ZoomCache();
@@ -97,6 +99,8 @@
private Rect mOriginalBounds = null;
private static int mZoomOrientation = ORI_NORMAL;
+ static final int MAX_BITMAP_DIM = 900;
+
private ReentrantLock mLoadingLock = new ReentrantLock();
public ImageLoader(FilterShowActivity activity, Context context) {
@@ -127,6 +131,13 @@
mLoadingLock.unlock();
return false;
}
+ if (MasterImage.getImage().supportsHighRes()) {
+ int highresPreviewSize = mOriginalBitmapLarge.getWidth() * 2;
+ if (highresPreviewSize > mOriginalBounds.width()) {
+ highresPreviewSize = mOriginalBounds.width();
+ }
+ mOriginalBitmapHighres = loadScaledBitmap(uri, highresPreviewSize, false);
+ }
updateBitmaps();
mLoadingLock.unlock();
return true;
@@ -197,6 +208,9 @@
if (mOrientation > 1) {
mOriginalBitmapSmall = rotateToPortrait(mOriginalBitmapSmall, mOrientation);
mOriginalBitmapLarge = rotateToPortrait(mOriginalBitmapLarge, mOrientation);
+ if (mOriginalBitmapHighres != null) {
+ mOriginalBitmapHighres = rotateToPortrait(mOriginalBitmapHighres, mOrientation);
+ }
}
mZoomOrientation = mOrientation;
warnListeners();
@@ -272,9 +286,11 @@
return null;
}
- static final int MAX_BITMAP_DIM = 900;
-
private Bitmap loadScaledBitmap(Uri uri, int size) {
+ return loadScaledBitmap(uri, size, true);
+ }
+
+ private Bitmap loadScaledBitmap(Uri uri, int size, boolean enforceSize) {
InputStream is = null;
try {
is = mContext.getContentResolver().openInputStream(uri);
@@ -291,7 +307,12 @@
int scale = 1;
while (true) {
- if (width_tmp <= MAX_BITMAP_DIM && height_tmp <= MAX_BITMAP_DIM) {
+ if (width_tmp <= 2 || height_tmp <= 2) {
+ break;
+ }
+ if (!enforceSize
+ || (width_tmp <= MAX_BITMAP_DIM
+ && height_tmp <= MAX_BITMAP_DIM)) {
if (width_tmp / 2 < size || height_tmp / 2 < size) {
break;
}
@@ -336,6 +357,10 @@
return mOriginalBitmapLarge;
}
+ public Bitmap getOriginalBitmapHighres() {
+ return mOriginalBitmapHighres;
+ }
+
public void addListener(ImageShow imageShow) {
mLoadingLock.lock();
if (!mListeners.contains(imageShow)) {
diff --git a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
index 138abb0..8e7c3e1 100644
--- a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
+++ b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
@@ -39,6 +39,7 @@
public static final int GEOMETRY_RENDERING = 2;
public static final int ICON_RENDERING = 3;
public static final int PARTIAL_RENDERING = 4;
+ public static final int HIGHRES_RENDERING = 5;
private static final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
public static void post(Bitmap source, ImagePreset preset, int type, RenderingRequestCaller caller) {
@@ -47,8 +48,10 @@
public static void post(Bitmap source, ImagePreset preset, int type,
RenderingRequestCaller caller, Rect bounds, Rect destination) {
- if ((type != PARTIAL_RENDERING && source == null) || preset == null || caller == null) {
- Log.v(LOGTAG, "something null: source: " + source + " or preset: " + preset + " or caller: " + caller);
+ if (((type != PARTIAL_RENDERING && type != HIGHRES_RENDERING) && source == null)
+ || preset == null || caller == null) {
+ Log.v(LOGTAG, "something null: source: " + source
+ + " or preset: " + preset + " or caller: " + caller);
return;
}
RenderingRequest request = new RenderingRequest();
@@ -59,7 +62,7 @@
CachingPipeline pipeline = new CachingPipeline(
FiltersManager.getManager(), "Icon");
bitmap = pipeline.renderGeometryIcon(source, preset);
- } else if (type != PARTIAL_RENDERING) {
+ } else if (type != PARTIAL_RENDERING && type != HIGHRES_RENDERING) {
bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), mConfig);
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
index 38dc177..1ab9e54 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
@@ -323,7 +323,11 @@
canvas.scale(scaleFactor, scaleFactor, cx, cy);
canvas.translate(translation.x, translation.y);
drawBackground(canvas);
- drawImage(canvas, getFilteredImage());
+ drawImage(canvas, getFilteredImage(), true);
+ Bitmap highresPreview = MasterImage.getImage().getHighresImage();
+ if (highresPreview != null) {
+ drawImage(canvas, highresPreview, false);
+ }
canvas.restore();
if (showTitle() && getImagePreset() != null) {
@@ -374,7 +378,7 @@
return MasterImage.getImage().getFilteredImage();
}
- public void drawImage(Canvas canvas, Bitmap image) {
+ public void drawImage(Canvas canvas, Bitmap image, boolean updateBounds) {
if (image != null) {
Rect s = new Rect(0, 0, image.getWidth(),
image.getHeight());
@@ -389,7 +393,9 @@
Rect d = new Rect((int) tx, (int) ty, (int) (w + tx),
(int) (h + ty));
- mImageBounds = d;
+ if (updateBounds) {
+ mImageBounds = d;
+ }
canvas.drawBitmap(image, s, d, mPaint);
}
}
@@ -420,7 +426,7 @@
Rect d = new Rect(mImageBounds.left, mImageBounds.top,
mImageBounds.left + px, mImageBounds.top + py);
canvas.clipRect(d);
- drawImage(canvas, image);
+ drawImage(canvas, image, false);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
index 993f5d5..c4d5a06 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
@@ -19,15 +19,12 @@
import android.graphics.*;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
-import android.util.Log;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.HistoryAdapter;
import com.android.gallery3d.filtershow.ImageStateAdapter;
import com.android.gallery3d.filtershow.cache.*;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.presets.ImagePreset;
@@ -42,6 +39,8 @@
private static int sIconSeedSize = 128;
private static float sHistoryPreviewSize = 128.0f;
+ private boolean mSupportsHighRes = false;
+
private ImageFilter mCurrentFilter = null;
private ImagePreset mPreset = null;
private ImagePreset mGeometryOnlyPreset = null;
@@ -52,6 +51,7 @@
private Bitmap mGeometryOnlyBitmap = null;
private Bitmap mFiltersOnlyBitmap = null;
private Bitmap mPartialBitmap = null;
+ private Bitmap mHighresBitmap = null;
private ImageLoader mLoader = null;
private HistoryAdapter mHistory = null;
@@ -96,6 +96,10 @@
return sMasterImage;
}
+ public void setSupportsHighRes(boolean value) {
+ mSupportsHighRes = value;
+ }
+
public static void setIconSeedSize(int iconSeedSize) {
sIconSeedSize = iconSeedSize;
}
@@ -253,6 +257,10 @@
return mPartialBitmap;
}
+ public Bitmap getHighresImage() {
+ return mHighresBitmap;
+ }
+
public void notifyObservers() {
for (ImageShow observer : mObservers) {
observer.invalidate();
@@ -283,7 +291,6 @@
}
}
invalidatePreview();
- needsUpdateFullResPreview();
mActivity.enableSave(hasModifications());
}
@@ -307,17 +314,27 @@
}
}
+ public void invalidateHighresPreview() {
+ if (mHighresBitmap != null) {
+ mHighresBitmap = null;
+ notifyObservers();
+ }
+ }
+
public void invalidatePreview() {
mFilteredPreview.invalidate();
invalidatePartialPreview();
- needsUpdateFullResPreview();
+ invalidateHighresPreview();
+ needsUpdatePartialPreview();
+ needsUpdateHighResPreview();
FilteringPipeline.getPipeline().updatePreviewBuffer();
}
public void setImageShowSize(int w, int h) {
if (mImageShowSize.x != w || mImageShowSize.y != h) {
mImageShowSize.set(w, h);
- needsUpdateFullResPreview();
+ needsUpdatePartialPreview();
+ needsUpdateHighResPreview();
}
}
@@ -345,7 +362,15 @@
return invert;
}
- public void needsUpdateFullResPreview() {
+ public void needsUpdateHighResPreview() {
+ if (!mSupportsHighRes) {
+ return;
+ }
+ RenderingRequest.post(null, mPreset, RenderingRequest.HIGHRES_RENDERING, this);
+ invalidateHighresPreview();
+ }
+
+ public void needsUpdatePartialPreview() {
if (!mPreset.canDoPartialRendering()) {
invalidatePartialPreview();
return;
@@ -376,6 +401,11 @@
mPartialBitmap = request.getBitmap();
notifyObservers();
}
+ if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
+ mHighresBitmap = request.getBitmap();
+ notifyObservers();
+ }
+
if (request.getType() == RenderingRequest.ICON_RENDERING) {
// History preview images
ImagePreset preset = request.getOriginalImagePreset();
@@ -426,7 +456,7 @@
public void setTranslation(Point translation) {
mTranslation.x = translation.x;
mTranslation.y = translation.y;
- needsUpdateFullResPreview();
+ needsUpdatePartialPreview();
}
public Point getOriginalTranslation() {
@@ -441,7 +471,7 @@
public void resetTranslation() {
mTranslation.x = 0;
mTranslation.y = 0;
- needsUpdateFullResPreview();
+ needsUpdatePartialPreview();
}
public Bitmap getThumbnailBitmap() {
@@ -455,4 +485,8 @@
public void setMaxScaleFactor(float maxScaleFactor) {
mMaxScaleFactor = maxScaleFactor;
}
+
+ public boolean supportsHighRes() {
+ return mSupportsHighRes;
+ }
}