Image loading optimizations
- Fix potential memory cache miss - Reduce `SizeResolver` allocations - Make data source type more accurate
This commit is contained in:
1 parent
dc4ea5e96d
commit
bcedbd85ef
5 files changed
+17
-30
No files matched your search
@@ -6,18 +6,19 @@ import androidx.paging.compose.LazyPagingItems
|
||||
import coil3.decode.BlackholeDecoder
|
||||
import coil3.request.CachePolicy
|
||||
import coil3.request.ImageRequest
|
||||
import coil3.size.Size
|
||||
import coil3.size.SizeResolver
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.client.data.GalleryPreview
|
||||
import com.hippo.ehviewer.client.data.V2GalleryPreview
|
||||
import com.hippo.ehviewer.client.thumbUrl
|
||||
import com.hippo.ehviewer.dao.DownloadInfo
|
||||
import com.hippo.ehviewer.download.DownloadManager
|
||||
import com.hippo.ehviewer.ktbuilder.execute
|
||||
|
||||
// Load in original size so the memory cache can be reused for preload requests
|
||||
fun ImageRequest.Builder.ehUrl(info: GalleryInfo) = apply {
|
||||
val key = info.thumbKey!!
|
||||
data(info.thumbUrl)
|
||||
size(SizeResolver.ORIGINAL)
|
||||
val downloadInfo = (info as? DownloadInfo) ?: DownloadManager.getDownloadInfo(info.gid)
|
||||
if (downloadInfo != null) {
|
||||
downloadInfo(downloadInfo)
|
||||
@@ -26,10 +27,11 @@ fun ImageRequest.Builder.ehUrl(info: GalleryInfo) = apply {
|
||||
diskCacheKey(key)
|
||||
}
|
||||
|
||||
// Load in original size so the memory cache can be reused for preload requests
|
||||
fun ImageRequest.Builder.ehPreview(preview: GalleryPreview) = apply {
|
||||
with(preview) {
|
||||
data(url)
|
||||
if (preview is V2GalleryPreview) size(Size.ORIGINAL)
|
||||
size(SizeResolver.ORIGINAL)
|
||||
memoryCacheKey(imageKey)
|
||||
diskCacheKey(imageKey)
|
||||
}
|
||||
|
||||
@@ -55,7 +55,9 @@ object MergeInterceptor : Interceptor {
|
||||
val cached = req.context.imageLoader.memoryCache!![cacheKey] != null
|
||||
val result = TightRopeTracker.use(key) { sendAndAwait { chain.proceed() } }
|
||||
when (result) {
|
||||
is SuccessResult if !cached -> result.copy(dataSource = DataSource.MEMORY)
|
||||
is SuccessResult if !cached && result.dataSource == DataSource.MEMORY_CACHE -> {
|
||||
result.copy(dataSource = DataSource.MEMORY)
|
||||
}
|
||||
else -> result
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -34,6 +34,8 @@ import coil3.request.SuccessResult
|
||||
import coil3.request.allowHardware
|
||||
import coil3.size.Dimension
|
||||
import coil3.size.Precision
|
||||
import coil3.size.Size
|
||||
import coil3.size.SizeResolver
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.coil.BitmapImageWithExtraInfo
|
||||
import com.hippo.ehviewer.coil.detectQrCode
|
||||
@@ -85,12 +87,13 @@ class Image private constructor(image: CoilImage, private val src: ImageSource)
|
||||
|
||||
companion object {
|
||||
private val targetWidth = appCtx.resources.displayMetrics.widthPixels * 3
|
||||
private val sizeResolver = SizeResolver(Size(targetWidth, Dimension.Undefined))
|
||||
|
||||
private suspend fun Either<ByteBufferSource, PathSource>.decodeCoil(checkExtraneousAds: Boolean): CoilImage {
|
||||
val request = appCtx.imageRequest {
|
||||
onLeft { data(it.source) }
|
||||
onRight { data(it.source.toUri()) }
|
||||
size(Dimension(targetWidth), Dimension.Undefined)
|
||||
size(sizeResolver)
|
||||
precision(Precision.INEXACT)
|
||||
allowHardware(false)
|
||||
hardwareThreshold(Settings.hardwareBitmapThreshold)
|
||||
|
||||
@@ -17,9 +17,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import coil3.compose.AsyncImagePainter
|
||||
import coil3.compose.ConstraintsSizeResolver
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberConstraintsSizeResolver
|
||||
import coil3.request.ImageRequest
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.ktbuilder.imageRequest
|
||||
@@ -33,25 +31,7 @@ import com.hippo.ehviewer.ui.tools.thenIf
|
||||
@NonRestartableComposable
|
||||
fun requestOf(model: GalleryInfo): ImageRequest {
|
||||
val context = LocalContext.current
|
||||
return remember(model) { context.imageRequest(model) }.withSizeResolver()
|
||||
}
|
||||
|
||||
@Composable
|
||||
@NonRestartableComposable
|
||||
fun ImageRequest.withSizeResolver() = if (defined.sizeResolver != null) {
|
||||
this
|
||||
} else {
|
||||
val sizeResolver = rememberConstraintsSizeResolver()
|
||||
remember(this, sizeResolver) { newBuilder().size(sizeResolver).build() }
|
||||
}
|
||||
|
||||
fun Modifier.imageRequest(request: ImageRequest): Modifier {
|
||||
val sizeResolver = request.sizeResolver
|
||||
return if (sizeResolver is ConstraintsSizeResolver) {
|
||||
then(sizeResolver)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
return remember(model) { context.imageRequest(model) }
|
||||
}
|
||||
|
||||
context(SharedTransitionScope, TransitionsVisibilityScope, SETNodeGenerator)
|
||||
@@ -73,7 +53,7 @@ fun EhAsyncCropThumb(
|
||||
},
|
||||
),
|
||||
contentDescription = null,
|
||||
modifier = modifier.imageRequest(request),
|
||||
modifier = modifier,
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
@@ -102,7 +82,7 @@ fun EhThumbCard(
|
||||
modifier = Modifier.thenIf(state !is AsyncImagePainter.State.Success) {
|
||||
// Keep applying this when state is `Loading` to avoid cutting off the ripple
|
||||
clickable { if (state is AsyncImagePainter.State.Error) painter.restart() }
|
||||
}.imageRequest(request).fillMaxSize(),
|
||||
}.fillMaxSize(),
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import com.hippo.ehviewer.ui.tools.shouldCrop
|
||||
@NonRestartableComposable
|
||||
fun requestOf(model: GalleryPreview): ImageRequest {
|
||||
val context = LocalContext.current
|
||||
return remember(model) { context.imageRequest(model) }.withSizeResolver()
|
||||
return remember(model) { context.imageRequest(model) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -88,7 +88,7 @@ fun EhPreviewCard(
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.imageRequest(request).fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user