Skip to content

Commit

Permalink
Add an experimental rememberGlidePainter API
Browse files Browse the repository at this point in the history
  • Loading branch information
sjudd committed Jul 9, 2023
1 parent fd96de2 commit c37b7b0
Show file tree
Hide file tree
Showing 18 changed files with 540 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.app.Application;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RawRes;
import androidx.benchmark.BenchmarkState;
Expand Down Expand Up @@ -111,17 +112,17 @@ private void loadImageWithExpectedDataSource(
public boolean onLoadFailed(
@Nullable GlideException e,
Object model,
Target<Bitmap> target,
@NonNull Target<Bitmap> target,
boolean isFirstResource) {
return false;
}

@Override
public boolean onResourceReady(
Bitmap resource,
Object model,
@NonNull Bitmap resource,
@NonNull Object model,
Target<Bitmap> target,
DataSource dataSource,
@NonNull DataSource dataSource,
boolean isFirstResource) {
dataSourceRef.set(dataSource);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ public void thumbnail_onResourceReady_forPrimary_isComplete_whenRequestListenerI
public boolean onLoadFailed(
@Nullable GlideException e,
Object model,
Target<Drawable> target,
@NonNull Target<Drawable> target,
boolean isFirstResource) {
return false;
}

@Override
public boolean onResourceReady(
Drawable resource,
Object model,
@NonNull Drawable resource,
@NonNull Object model,
Target<Drawable> target,
DataSource dataSource,
@NonNull DataSource dataSource,
boolean isFirstResource) {
isPrimaryRequestComplete.set(target.getRequest().isComplete());
countDownLatch.countDown();
Expand Down Expand Up @@ -115,7 +115,7 @@ public void thumbnail_onLoadFailed_forPrimary_isNotRunningOrComplete_whenRequest
public boolean onLoadFailed(
@Nullable GlideException e,
Object model,
Target<Drawable> target,
@NonNull Target<Drawable> target,
boolean isFirstResource) {
Request request = target.getRequest();
isNeitherRunningNorComplete.set(!request.isComplete() && !request.isRunning());
Expand All @@ -125,10 +125,10 @@ public boolean onLoadFailed(

@Override
public boolean onResourceReady(
Drawable resource,
Object model,
@NonNull Drawable resource,
@NonNull Object model,
Target<Drawable> target,
DataSource dataSource,
@NonNull DataSource dataSource,
boolean isFirstResource) {
return false;
}
Expand Down
57 changes: 57 additions & 0 deletions integration/compose/api/compose.api
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
public final class com/bumptech/glide/integration/compose/AnimationState : java/lang/Enum {
public static final field Animate Lcom/bumptech/glide/integration/compose/AnimationState;
public static final field Failed Lcom/bumptech/glide/integration/compose/AnimationState;
public static final field Loading Lcom/bumptech/glide/integration/compose/AnimationState;
public static final field Success Lcom/bumptech/glide/integration/compose/AnimationState;
public static fun valueOf (Ljava/lang/String;)Lcom/bumptech/glide/integration/compose/AnimationState;
public static fun values ()[Lcom/bumptech/glide/integration/compose/AnimationState;
}

public abstract interface annotation class com/bumptech/glide/integration/compose/ExperimentalGlideComposeApi : java/lang/annotation/Annotation {
}

Expand All @@ -8,6 +17,54 @@ public final class com/bumptech/glide/integration/compose/GlideImageKt {
public static final fun placeholder (Lkotlin/jvm/functions/Function2;)Lcom/bumptech/glide/integration/compose/Placeholder;
}

public final class com/bumptech/glide/integration/compose/GlidePainterKt {
public static final fun animate (Lcom/bumptech/glide/integration/compose/GlidePainterState;)Lcom/bumptech/glide/integration/compose/AnimationState;
public static final fun rememberGlidePainter (Ljava/lang/Object;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Lcom/bumptech/glide/integration/compose/GlidePainterStateAndModifier;
public static final fun rememberGlidePainter (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Lkotlin/Pair;
}

public abstract class com/bumptech/glide/integration/compose/GlidePainterState {
public static final field $stable I
}

public final class com/bumptech/glide/integration/compose/GlidePainterState$Failure : com/bumptech/glide/integration/compose/GlidePainterState {
public static final field $stable I
public static final field INSTANCE Lcom/bumptech/glide/integration/compose/GlidePainterState$Failure;
}

public final class com/bumptech/glide/integration/compose/GlidePainterState$Loading : com/bumptech/glide/integration/compose/GlidePainterState {
public static final field $stable I
public static final field INSTANCE Lcom/bumptech/glide/integration/compose/GlidePainterState$Loading;
}

public final class com/bumptech/glide/integration/compose/GlidePainterState$Success : com/bumptech/glide/integration/compose/GlidePainterState {
public static final field $stable I
public fun <init> (Lcom/bumptech/glide/load/DataSource;)V
public final fun component1 ()Lcom/bumptech/glide/load/DataSource;
public final fun copy (Lcom/bumptech/glide/load/DataSource;)Lcom/bumptech/glide/integration/compose/GlidePainterState$Success;
public static synthetic fun copy$default (Lcom/bumptech/glide/integration/compose/GlidePainterState$Success;Lcom/bumptech/glide/load/DataSource;ILjava/lang/Object;)Lcom/bumptech/glide/integration/compose/GlidePainterState$Success;
public fun equals (Ljava/lang/Object;)Z
public final fun getDataSource ()Lcom/bumptech/glide/load/DataSource;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/bumptech/glide/integration/compose/GlidePainterStateAndModifier {
public static final field $stable I
public fun <init> (Landroidx/compose/ui/graphics/painter/Painter;Lcom/bumptech/glide/integration/compose/GlidePainterState;Landroidx/compose/ui/Modifier;)V
public final fun component1 ()Landroidx/compose/ui/graphics/painter/Painter;
public final fun component2 ()Lcom/bumptech/glide/integration/compose/GlidePainterState;
public final fun component3 ()Landroidx/compose/ui/Modifier;
public final fun copy (Landroidx/compose/ui/graphics/painter/Painter;Lcom/bumptech/glide/integration/compose/GlidePainterState;Landroidx/compose/ui/Modifier;)Lcom/bumptech/glide/integration/compose/GlidePainterStateAndModifier;
public static synthetic fun copy$default (Lcom/bumptech/glide/integration/compose/GlidePainterStateAndModifier;Landroidx/compose/ui/graphics/painter/Painter;Lcom/bumptech/glide/integration/compose/GlidePainterState;Landroidx/compose/ui/Modifier;ILjava/lang/Object;)Lcom/bumptech/glide/integration/compose/GlidePainterStateAndModifier;
public fun equals (Ljava/lang/Object;)Z
public final fun getModifier ()Landroidx/compose/ui/Modifier;
public final fun getPainter ()Landroidx/compose/ui/graphics/painter/Painter;
public final fun getState ()Lcom/bumptech/glide/integration/compose/GlidePainterState;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public abstract interface class com/bumptech/glide/integration/compose/GlidePreloadingData {
public abstract fun get (ILandroidx/compose/runtime/Composer;I)Lkotlin/Pair;
public abstract fun getSize ()I
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,17 +295,17 @@ class GlideImageTest {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
target: Target<Drawable>,
isFirstResource: Boolean,
): Boolean {
throw UnsupportedOperationException()
}

override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
resource: Drawable,
model: Any,
target: Target<Drawable>,
dataSource: DataSource,
isFirstResource: Boolean,
): Boolean {
onResourceReadyCounter.incrementAndGet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
Expand All @@ -22,12 +21,10 @@ import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.RequestManager
import com.bumptech.glide.integration.ktx.AsyncGlideSize
import com.bumptech.glide.integration.ktx.ExperimentGlideFlows
import com.bumptech.glide.integration.ktx.ImmediateGlideSize
import com.bumptech.glide.integration.ktx.InternalGlideApi
import com.bumptech.glide.integration.ktx.ResolvableGlideSize
import com.bumptech.glide.integration.ktx.Size
import com.bumptech.glide.integration.ktx.Status
import com.google.accompanist.drawablepainter.rememberDrawablePainter

/** Mutates and returns the given [RequestBuilder] to apply relevant options. */
Expand Down Expand Up @@ -129,6 +126,7 @@ public fun GlideImage(
)
}


@OptIn(ExperimentalGlideComposeApi::class)
@Composable
private fun PreviewResourceOrDrawable(
Expand Down Expand Up @@ -229,7 +227,7 @@ public sealed class Placeholder {

@OptIn(InternalGlideApi::class)
@Composable
private fun rememberResolvableSize(
internal fun rememberResolvableSize(
overrideSize: Size?,
) =
remember(overrideSize) {
Expand Down Expand Up @@ -269,7 +267,7 @@ private fun RequestBuilder<Drawable>.contentScaleTransform(
// TODO(judds): Think about how to handle the various fills
}

@OptIn(InternalGlideApi::class, ExperimentGlideFlows::class)
@OptIn(InternalGlideApi::class, ExperimentalGlideComposeApi::class)
@Composable
private fun SizedGlideImage(
requestBuilder: RequestBuilder<Drawable>,
Expand All @@ -290,10 +288,11 @@ private fun SizedGlideImage(
rememberGlidePainter(
requestBuilder = requestBuilder,
size = size,
resolveSize = true
)
if (placeholder != null && painter.status.showPlaceholder()) {
if (placeholder != null && (painter.state is GlidePainterState.Loading)) {
placeholder.boxed()
} else if (failure != null && painter.status == Status.FAILED) {
} else if (failure != null && painter.state is GlidePainterState.Failure) {
failure.boxed()
} else {
Image(
Expand All @@ -308,26 +307,6 @@ private fun SizedGlideImage(
}
}

@OptIn(ExperimentGlideFlows::class)
private fun Status.showPlaceholder(): Boolean =
when (this) {
Status.RUNNING -> true
Status.CLEARED -> true
else -> false
}

@OptIn(InternalGlideApi::class)
@Composable
private fun rememberGlidePainter(
requestBuilder: RequestBuilder<Drawable>,
size: ResolvableGlideSize,
): GlidePainter {
val scope = rememberCoroutineScope()
// TODO(judds): Calling onRemembered here manually might make a minor improvement in how quickly
// the image load is started, but it also triggers a recomposition. I can't figure out why it
// triggers a recomposition
return remember(requestBuilder, size) { GlidePainter(requestBuilder, size, scope) }
}

internal val DisplayedDrawableKey =
SemanticsPropertyKey<MutableState<Drawable?>>("DisplayedDrawable")
Expand Down
Loading

0 comments on commit c37b7b0

Please sign in to comment.