Remove DrawImageWithPipeline from Nodes
Summary: Nodes historically had two image implementations - DrawImageWithDrawee and DrawImageWithPipeline. The drawee implementation was the default (per request of the Fresco team). At this point, there is no point of having two (especially since updates to one need to be made to the other), so this patch removes pipeline. Reviewed By: sriramramani Differential Revision: D3755523
This commit is contained in:
parent
82a4017ecd
commit
8cff05101a
|
@ -17,7 +17,7 @@ import com.facebook.drawee.drawable.ScalingUtils.ScaleType;
|
|||
import com.facebook.react.bridge.ReadableArray;
|
||||
|
||||
/**
|
||||
* Common interface for DrawImageWithPipeline and DrawImageWithDrawee.
|
||||
* Common interface for DrawImageWithDrawee.
|
||||
*/
|
||||
/* package */ interface DrawImage extends AttachDetachListener {
|
||||
/**
|
||||
|
|
|
@ -1,318 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.flat;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Shader;
|
||||
|
||||
import com.facebook.drawee.drawable.ScalingUtils.ScaleType;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.views.image.ImageResizeMode;
|
||||
import com.facebook.react.views.image.ReactImageView;
|
||||
import com.facebook.react.views.imagehelper.ImageSource;
|
||||
import com.facebook.react.views.imagehelper.MultiSourceHelper;
|
||||
import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult;
|
||||
|
||||
/**
|
||||
* DrawImageWithPipeline is DrawCommand that can draw a local or remote image.
|
||||
* It uses PipelineRequestHelper internally to fetch and cache the images.
|
||||
*/
|
||||
/* package */ final class DrawImageWithPipeline extends AbstractDrawBorder
|
||||
implements DrawImage, BitmapUpdateListener {
|
||||
|
||||
private static final Paint PAINT = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
private static final int BORDER_BITMAP_PATH_DIRTY = 1 << 1;
|
||||
|
||||
private final List<ImageSource> mSources = new LinkedList<>();
|
||||
private final Matrix mTransform = new Matrix();
|
||||
private ScaleType mScaleType = ImageResizeMode.defaultValue();
|
||||
private @Nullable PipelineRequestHelper mRequestHelper;
|
||||
private @Nullable PorterDuffColorFilter mColorFilter;
|
||||
private @Nullable FlatViewGroup.InvalidateCallback mCallback;
|
||||
private @Nullable Path mPathForRoundedBitmap;
|
||||
private @Nullable BitmapShader mBitmapShader;
|
||||
private float mHorizontalPadding;
|
||||
private float mVerticalPadding;
|
||||
private int mReactTag;
|
||||
|
||||
// variables used for fading the image in
|
||||
private long mFirstDrawTime = -1;
|
||||
private boolean mProgressiveRenderingEnabled;
|
||||
private int mFadeDuration = ReactImageView.REMOTE_IMAGE_FADE_DURATION_MS;
|
||||
|
||||
@Override
|
||||
public boolean hasImageRequest() {
|
||||
return !mSources.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Context context, @Nullable ReadableArray sources) {
|
||||
mSources.clear();
|
||||
if (sources != null && sources.size() != 0) {
|
||||
// Optimize for the case where we have just one uri, case in which we don't need the sizes
|
||||
if (sources.size() == 1) {
|
||||
ReadableMap source = sources.getMap(0);
|
||||
mSources.add(new ImageSource(context, source.getString("uri")));
|
||||
} else {
|
||||
for (int idx = 0; idx < sources.size(); idx++) {
|
||||
ReadableMap source = sources.getMap(idx);
|
||||
mSources.add(new ImageSource(
|
||||
context,
|
||||
source.getString("uri"),
|
||||
source.getDouble("width"),
|
||||
source.getDouble("height")));
|
||||
}
|
||||
}
|
||||
}
|
||||
mBitmapShader = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTintColor(int tintColor) {
|
||||
if (tintColor == 0) {
|
||||
mColorFilter = null;
|
||||
} else {
|
||||
mColorFilter = new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleType(ScaleType scaleType) {
|
||||
mScaleType = scaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleType getScaleType() {
|
||||
return mScaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReactTag(int reactTag) {
|
||||
mReactTag = reactTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFadeDuration(int fadeDuration) {
|
||||
mFadeDuration = fadeDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressiveRenderingEnabled(boolean enabled) {
|
||||
mProgressiveRenderingEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the bitmap isn't loaded by the first draw, fade it in, otherwise don't fade.
|
||||
*/
|
||||
@Override
|
||||
protected void onPreDraw(FlatViewGroup parent, Canvas canvas) {
|
||||
super.onPreDraw(parent, canvas);
|
||||
|
||||
Bitmap bitmap = Assertions.assumeNotNull(mRequestHelper).getBitmap();
|
||||
if (bitmap == null) {
|
||||
mFirstDrawTime = 0;
|
||||
} else {
|
||||
if (mFirstDrawTime == -1) {
|
||||
PAINT.setAlpha(255);
|
||||
} else {
|
||||
long currentDrawingTime = parent.getDrawingTime();
|
||||
if (mFirstDrawTime == 0) {
|
||||
mFirstDrawTime = currentDrawingTime - 16; // -16 to skip one draw cycle, so that we start
|
||||
// with a non-zero alpha (otherwise, we waste 16ms doing nothing during this cycle).
|
||||
}
|
||||
int alpha = (int) (255.0f * (1.0f * (currentDrawingTime - mFirstDrawTime) / mFadeDuration));
|
||||
if (alpha >= 255) {
|
||||
mFirstDrawTime = -1;
|
||||
alpha = 255;
|
||||
} else {
|
||||
Assertions.assumeNotNull(mCallback).invalidate();
|
||||
}
|
||||
PAINT.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
Bitmap bitmap = Assertions.assumeNotNull(mRequestHelper).getBitmap();
|
||||
if (bitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PAINT.setColorFilter(mColorFilter);
|
||||
|
||||
if (getBorderRadius() < 0.5f) {
|
||||
canvas.drawBitmap(bitmap, mTransform, PAINT);
|
||||
} else {
|
||||
if (mBitmapShader == null) {
|
||||
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
mBitmapShader.setLocalMatrix(mTransform);
|
||||
}
|
||||
PAINT.setShader(mBitmapShader);
|
||||
canvas.drawPath(getPathForRoundedBitmap(), PAINT);
|
||||
}
|
||||
|
||||
drawBorders(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldClip() {
|
||||
return getLeft() + mHorizontalPadding < getClipLeft() ||
|
||||
getTop() + mVerticalPadding < getClipTop() ||
|
||||
getRight() - mHorizontalPadding > getClipRight() ||
|
||||
getBottom() - mVerticalPadding < getClipBottom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBorderRadius(float borderRadius) {
|
||||
super.setBorderRadius(borderRadius);
|
||||
setFlag(BORDER_BITMAP_PATH_DIRTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttached(FlatViewGroup.InvalidateCallback callback) {
|
||||
mCallback = callback;
|
||||
Assertions.assumeNotNull(mRequestHelper).attach(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetached() {
|
||||
Assertions.assumeNotNull(mRequestHelper).detach();
|
||||
|
||||
if (mRequestHelper.isDetached()) {
|
||||
// Make sure we don't hold on to the Bitmap.
|
||||
mBitmapShader = null;
|
||||
// this is optional
|
||||
mCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChanged() {
|
||||
super.onBoundsChanged();
|
||||
setFlag(BORDER_BITMAP_PATH_DIRTY);
|
||||
computeRequestHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSecondaryAttach(Bitmap bitmap) {
|
||||
updateBounds(bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBitmapReady(Bitmap bitmap) {
|
||||
updateBounds(bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImageLoadEvent(int imageLoadEvent) {
|
||||
if (mReactTag != 0 && mCallback != null) {
|
||||
mCallback.dispatchImageLoadEvent(mReactTag, imageLoadEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private void computeRequestHelper() {
|
||||
MultiSourceResult multiSource = MultiSourceHelper.getBestSourceForSize(
|
||||
Math.round(getRight() - getLeft()),
|
||||
Math.round(getBottom() - getTop()),
|
||||
mSources);
|
||||
ImageSource source = multiSource.getBestResult();
|
||||
if (source == null) {
|
||||
mRequestHelper = null;
|
||||
return;
|
||||
}
|
||||
ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(source.getUri())
|
||||
.setProgressiveRenderingEnabled(mProgressiveRenderingEnabled)
|
||||
.build();
|
||||
|
||||
// DrawImageWithPipeline does now support displaying low res cache images before request
|
||||
mRequestHelper = new PipelineRequestHelper(Assertions.assertNotNull(imageRequest));
|
||||
}
|
||||
|
||||
/* package */ void updateBounds(Bitmap bitmap) {
|
||||
Assertions.assumeNotNull(mCallback).invalidate();
|
||||
|
||||
float left = getLeft();
|
||||
float top = getTop();
|
||||
|
||||
float containerWidth = getRight() - left;
|
||||
float containerHeight = getBottom() - top;
|
||||
|
||||
float imageWidth = (float) bitmap.getWidth();
|
||||
float imageHeight = (float) bitmap.getHeight();
|
||||
|
||||
if (mScaleType == ScaleType.FIT_XY) {
|
||||
mTransform.setScale(containerWidth / imageWidth, containerHeight / imageHeight);
|
||||
mTransform.postTranslate(left, top);
|
||||
mHorizontalPadding = mVerticalPadding = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
final float scale;
|
||||
|
||||
if (mScaleType == ScaleType.CENTER_INSIDE) {
|
||||
if (containerWidth >= imageWidth && containerHeight >= imageHeight) {
|
||||
scale = 1.0f;
|
||||
} else {
|
||||
scale = Math.min(containerWidth / imageWidth, containerHeight / imageHeight);
|
||||
}
|
||||
} else {
|
||||
scale = Math.max(containerWidth / imageWidth, containerHeight / imageHeight);
|
||||
}
|
||||
|
||||
mHorizontalPadding = (containerWidth - imageWidth * scale) / 2;
|
||||
mVerticalPadding = (containerHeight - imageHeight * scale) / 2;
|
||||
|
||||
mTransform.setScale(scale, scale);
|
||||
mTransform.postTranslate(left + mHorizontalPadding, top + mVerticalPadding);
|
||||
|
||||
if (mBitmapShader != null) {
|
||||
mBitmapShader.setLocalMatrix(mTransform);
|
||||
}
|
||||
}
|
||||
|
||||
private Path getPathForRoundedBitmap() {
|
||||
if (isFlagSet(BORDER_BITMAP_PATH_DIRTY)) {
|
||||
if (mPathForRoundedBitmap == null) {
|
||||
mPathForRoundedBitmap = new Path();
|
||||
}
|
||||
|
||||
updatePath(mPathForRoundedBitmap, 1.0f);
|
||||
|
||||
resetFlag(BORDER_BITMAP_PATH_DIRTY);
|
||||
}
|
||||
|
||||
return mPathForRoundedBitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDebugDrawHighlight(Canvas canvas) {
|
||||
if (mCallback != null) {
|
||||
debugDrawCautionHighlight(canvas, "Invalidate Pipeline");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,8 +11,6 @@ package com.facebook.react.flat;
|
|||
|
||||
/* package */ final class RCTImageViewManager extends FlatViewManager {
|
||||
|
||||
private static final boolean USE_IMAGEPIPELINE_DIRECTLY = false;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "RCTImageView";
|
||||
|
@ -20,11 +18,7 @@ package com.facebook.react.flat;
|
|||
|
||||
@Override
|
||||
public RCTImageView createShadowNodeInstance() {
|
||||
if (USE_IMAGEPIPELINE_DIRECTLY) {
|
||||
return new RCTImageView(new DrawImageWithPipeline());
|
||||
} else {
|
||||
return new RCTImageView(new DrawImageWithDrawee());
|
||||
}
|
||||
return new RCTImageView(new DrawImageWithDrawee());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue