Drastically reduce number of projection instances we create.

Via SimplePool
This commit is contained in:
Alex Hart
2021-10-25 14:12:08 -03:00
committed by GitHub
parent 98fce53cf1
commit b34bb2e7d7
12 changed files with 145 additions and 64 deletions

View File

@@ -57,6 +57,7 @@ import org.thoughtcrime.securesms.util.CachedInflater;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.MessageRecordUtil;
import org.thoughtcrime.securesms.util.Projection;
import org.thoughtcrime.securesms.util.ProjectionList;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
@@ -704,7 +705,7 @@ public class ConversationAdapter
}
@Override
public @NonNull List<Projection> getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
public @NonNull ProjectionList getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
return getBindable().getColorizerProjections(coordinateRoot);
}
}

View File

@@ -122,6 +122,7 @@ import org.thoughtcrime.securesms.util.InterceptableLongClickCopyLinkSpan;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
import org.thoughtcrime.securesms.util.MessageRecordUtil;
import org.thoughtcrime.securesms.util.Projection;
import org.thoughtcrime.securesms.util.ProjectionList;
import org.thoughtcrime.securesms.util.SearchUtil;
import org.thoughtcrime.securesms.util.StringUtil;
import org.thoughtcrime.securesms.util.ThemeUtil;
@@ -221,6 +222,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
private Colorizer colorizer;
private boolean hasWallpaper;
private float lastYDownRelativeToThis;
private ProjectionList colorizerProjections = new ProjectionList(3);
public ConversationItem(Context context) {
this(context, null);
@@ -530,6 +532,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if (conversationRecipient != null) {
conversationRecipient.removeForeverObserver(this);
}
bodyBubble.setVideoPlayerProjection(null);
bodyBubble.setQuoteViewProjection(null);
cancelPulseOutlinerAnimation();
}
@@ -588,12 +594,17 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
}
private static int getProjectionTop(@NonNull View child) {
return (int) Projection.relativeToViewRoot(child, null).getY();
Projection projection = Projection.relativeToViewRoot(child, null);
int y = (int) projection.getY();
projection.release();
return y;
}
private static int getProjectionBottom(@NonNull View child) {
Projection projection = Projection.relativeToViewRoot(child, null);
return (int) projection.getY() + projection.getHeight();
int bottom = (int) projection.getY() + projection.getHeight();
projection.release();
return bottom;
}
@Override
@@ -1719,8 +1730,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
}
@Override
public @NonNull List<Projection> getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
List<Projection> projections = new LinkedList<>();
public @NonNull ProjectionList getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
colorizerProjections.clear();
if (messageRecord.isOutgoing() &&
!hasNoBubble(messageRecord) &&
@@ -1731,9 +1742,9 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
Projection videoToBubble = bodyBubble.getVideoPlayerProjection();
if (videoToBubble != null) {
Projection videoToRoot = Projection.translateFromDescendantToParentCoords(videoToBubble, bodyBubble, coordinateRoot);
projections.addAll(Projection.getCapAndTail(bodyBubbleToRoot, videoToRoot));
colorizerProjections.addAll(Projection.getCapAndTail(bodyBubbleToRoot, videoToRoot));
} else {
projections.add(bodyBubbleToRoot);
colorizerProjections.add(bodyBubbleToRoot);
}
}
@@ -1743,7 +1754,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
{
Projection footerProjection = getActiveFooter(messageRecord).getProjection(coordinateRoot);
if (footerProjection != null) {
projections.add(footerProjection.translateX(bodyBubble.getTranslationX()));
colorizerProjections.add(footerProjection.translateX(bodyBubble.getTranslationX()));
}
}
@@ -1752,10 +1763,14 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
quoteView != null)
{
bodyBubble.setQuoteViewProjection(quoteView.getProjection(bodyBubble));
projections.add(quoteView.getProjection(coordinateRoot).translateX(bodyBubble.getTranslationX() + this.getTranslationX()));
colorizerProjections.add(quoteView.getProjection(coordinateRoot).translateX(bodyBubble.getTranslationX() + this.getTranslationX()));
}
return projections.stream().map(p -> p.translateY(this.getTranslationY())).collect(Collectors.toList());
for (int i = 0; i < colorizerProjections.size(); i++) {
colorizerProjections.get(i).translateY(getTranslationY());
}
return colorizerProjections;
}
@Override

View File

@@ -63,11 +63,19 @@ public class ConversationItemBodyBubble extends LinearLayout {
}
public void setQuoteViewProjection(@Nullable Projection quoteViewProjection) {
if (this.quoteViewProjection != null) {
this.quoteViewProjection.release();
}
this.quoteViewProjection = quoteViewProjection;
clipProjectionDrawable.setProjections(getProjections());
}
public void setVideoPlayerProjection(@Nullable Projection videoPlayerProjection) {
if (this.videoPlayerProjection != null) {
this.videoPlayerProjection.release();
}
this.videoPlayerProjection = videoPlayerProjection;
clipProjectionDrawable.setProjections(getProjections());
}

View File

@@ -39,6 +39,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.IdentityUtil;
import org.thoughtcrime.securesms.util.Projection;
import org.thoughtcrime.securesms.util.ProjectionList;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
@@ -59,7 +60,9 @@ import java.util.concurrent.ExecutionException;
public final class ConversationUpdateItem extends FrameLayout
implements BindableConversationItem
{
private static final String TAG = Log.tag(ConversationUpdateItem.class);
private static final String TAG = Log.tag(ConversationUpdateItem.class);
private static final ProjectionList EMPTY_PROJECTION_LIST = new ProjectionList();
private Set<MultiselectPart> batchSelected;
@@ -221,8 +224,8 @@ public final class ConversationUpdateItem extends FrameLayout
}
@Override
public @NonNull List<Projection> getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
return Collections.emptyList();
public @NonNull ProjectionList getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
return EMPTY_PROJECTION_LIST;
}
@Override

View File

@@ -1,12 +1,12 @@
package org.thoughtcrime.securesms.conversation.colors
import android.view.ViewGroup
import org.thoughtcrime.securesms.util.Projection
import org.thoughtcrime.securesms.util.ProjectionList
/**
* Denotes that a class can be colorized. The class is responsible for
* generating its own projection.
*/
interface Colorizable {
fun getColorizerProjections(coordinateRoot: ViewGroup): List<Projection>
fun getColorizerProjections(coordinateRoot: ViewGroup): ProjectionList
}

View File

@@ -40,4 +40,9 @@ class ColorizerView @JvmOverloads constructor(
super.draw(canvas)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
projections.forEach { it.release() }
}
}

View File

@@ -98,8 +98,10 @@ class RecyclerViewColorizer(private val recyclerView: RecyclerView) {
if (child != null) {
val holder = parent.getChildViewHolder(child)
if (holder is Colorizable) {
holder.getColorizerProjections(parent).forEach {
c.drawPath(it.path, holePunchPaint)
holder.getColorizerProjections(parent).use { list ->
list.forEach {
c.drawPath(it.path, holePunchPaint)
}
}
}
}

View File

@@ -21,7 +21,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.airbnb.lottie.SimpleColorFilter
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.conversation.ConversationAdapter
import org.thoughtcrime.securesms.util.Projection
import org.thoughtcrime.securesms.util.SetUtil
import org.thoughtcrime.securesms.util.ThemeUtil
import org.thoughtcrime.securesms.util.ViewUtil
@@ -157,9 +156,17 @@ class MultiselectItemDecoration(
val parts: MultiselectCollection = child.conversationMessage.multiselectCollection
val projections: List<Projection> = child.getColorizerProjections(parent) + if (child.canPlayContent()) listOf(child.getGiphyMp4PlayableProjection(parent)) else emptyList()
val projections = child.getColorizerProjections(parent)
if (child.canPlayContent()) {
projections.add(child.getGiphyMp4PlayableProjection(parent))
}
path.reset()
projections.forEach { it.applyToPath(path) }
projections.use { list ->
list.forEach {
it.applyToPath(path)
}
}
canvas.save()
canvas.clipPath(path, Region.Op.DIFFERENCE)
@@ -341,13 +348,16 @@ class MultiselectItemDecoration(
parent.forEach { child ->
if (child is Multiselectable && child.conversationMessage == inFocus.conversationMessage) {
path.addRect(child.left.toFloat(), child.top.toFloat(), child.right.toFloat(), child.bottom.toFloat(), Path.Direction.CW)
child.getColorizerProjections(parent).forEach {
path.op(it.path, Path.Op.DIFFERENCE)
child.getColorizerProjections(parent).use { list ->
list.forEach {
path.op(it.path, Path.Op.DIFFERENCE)
}
}
if (child.canPlayContent()) {
val mp4GifProjection = child.getGiphyMp4PlayableProjection(child.rootView as ViewGroup)
path.op(mp4GifProjection.path, Path.Op.DIFFERENCE)
mp4GifProjection.release()
}
}
}