From: nicolasroard Date: Fri, 29 Mar 2013 21:41:38 +0000 (-0700) Subject: Implements progressive rendering X-Git-Tag: android-x86-6.0-r3~68^2~28^2~213^2~19^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2^2~428^2~2^2~201^2~120^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4dad1a9e3f213e95a4f419c06ea885fee75d3297;p=android-x86%2Fpackages-apps-Camera2.git Implements progressive rendering Change-Id: I32bd2072126a4fad4342f7d9ffa1cff3b5da84cf --- diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java index 409f1e366..8bbfc558d 100644 --- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java +++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java @@ -94,6 +94,8 @@ public class FilterShowActivity extends Activity implements OnItemClickListener, 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; @@ -487,7 +489,11 @@ public class FilterShowActivity extends Activity implements OnItemClickListener, 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; @@ -879,6 +885,12 @@ public class FilterShowActivity extends Activity implements OnItemClickListener, 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 bc1d4505d..ecfdabab0 100644 --- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java +++ b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java @@ -54,6 +54,7 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { } mPreviousGeometry = null; mPreviewScaleFactor = 1.0f; + mHighResPreviewScaleFactor = 1.0f; destroyPixelAllocations(); } @@ -149,13 +151,20 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { } } + 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 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { 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 @@ public class CachingPipeline { String thread = Thread.currentThread().getName(); long time = System.currentTimeMillis(); - setupEnvironment(preset); + setupEnvironment(preset, false); mFiltersManager.freeFilterResources(preset); Bitmap resizedOriginalBitmap = mResizedOriginalBitmap; @@ -346,11 +364,14 @@ public class CachingPipeline { 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 1ba6e959e..ce66b5bce 100644 --- a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java +++ b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java @@ -47,9 +47,23 @@ public class FilteringPipeline implements Handler.Callback { 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 @@ public class FilteringPipeline implements Handler.Callback { 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 @@ public class FilteringPipeline implements Handler.Callback { 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 @@ public class FilteringPipeline implements Handler.Callback { 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 a6a0bcf84..b4e98e114 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.FilterShowActivity; 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 @@ public class ImageLoader { private final Vector mListeners = new Vector(); 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 @@ public class ImageLoader { 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 @@ public class ImageLoader { 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 @@ public class ImageLoader { 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 @@ public class ImageLoader { 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 @@ public class ImageLoader { 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 @@ public class ImageLoader { 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 138abb0c9..8e7c3e195 100644 --- a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java +++ b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java @@ -39,6 +39,7 @@ public class RenderingRequest { 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 class RenderingRequest { 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 @@ public class RenderingRequest { 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 38dc17719..1ab9e5466 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java @@ -323,7 +323,11 @@ public class ImageShow extends View implements OnGestureListener, 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 @@ public class ImageShow extends View implements OnGestureListener, 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 @@ public class ImageShow extends View implements OnGestureListener, 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 @@ public class ImageShow extends View implements OnGestureListener, 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 993f5d5ec..c4d5a0677 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java @@ -19,15 +19,12 @@ package com.android.gallery3d.filtershow.imageshow; 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 @@ public class MasterImage implements RenderingRequestCaller { 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 @@ public class MasterImage implements RenderingRequestCaller { 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 @@ public class MasterImage implements RenderingRequestCaller { return sMasterImage; } + public void setSupportsHighRes(boolean value) { + mSupportsHighRes = value; + } + public static void setIconSeedSize(int iconSeedSize) { sIconSeedSize = iconSeedSize; } @@ -253,6 +257,10 @@ public class MasterImage implements RenderingRequestCaller { return mPartialBitmap; } + public Bitmap getHighresImage() { + return mHighresBitmap; + } + public void notifyObservers() { for (ImageShow observer : mObservers) { observer.invalidate(); @@ -283,7 +291,6 @@ public class MasterImage implements RenderingRequestCaller { } } invalidatePreview(); - needsUpdateFullResPreview(); mActivity.enableSave(hasModifications()); } @@ -307,17 +314,27 @@ public class MasterImage implements RenderingRequestCaller { } } + 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 @@ public class MasterImage implements RenderingRequestCaller { 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 @@ public class MasterImage implements RenderingRequestCaller { 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 class MasterImage implements RenderingRequestCaller { public void setTranslation(Point translation) { mTranslation.x = translation.x; mTranslation.y = translation.y; - needsUpdateFullResPreview(); + needsUpdatePartialPreview(); } public Point getOriginalTranslation() { @@ -441,7 +471,7 @@ public class MasterImage implements RenderingRequestCaller { public void resetTranslation() { mTranslation.x = 0; mTranslation.y = 0; - needsUpdateFullResPreview(); + needsUpdatePartialPreview(); } public Bitmap getThumbnailBitmap() { @@ -455,4 +485,8 @@ public class MasterImage implements RenderingRequestCaller { public void setMaxScaleFactor(float maxScaleFactor) { mMaxScaleFactor = maxScaleFactor; } + + public boolean supportsHighRes() { + return mSupportsHighRes; + } }