Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4dad1a9e authored by nicolasroard's avatar nicolasroard
Browse files

Implements progressive rendering

Change-Id: I32bd2072126a4fad4342f7d9ffa1cff3b5da84cf
parent 3f312857
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -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);
        }
    }

    // //////////////////////////////////////////////////////////////////////////////
+31 −10
Original line number Diff line number Diff line
@@ -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);
        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;
    }
+34 −4
Original line number Diff line number Diff line
@@ -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();
+28 −3
Original line number Diff line number Diff line
@@ -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<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 @@ 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)) {
+6 −3
Original line number Diff line number Diff line
@@ -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);
        }

Loading