From e6d96bd348ea5d18a005d6465222ad5f5123103e Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Sun, 17 Nov 2024 03:04:38 +0600 Subject: [PATCH] Switch to hardware bitmap in reader only if device can handle it Closes #1460 --- .../data/coil/TachiyomiImageDecoder.kt | 6 +-- .../ui/reader/viewer/ReaderPageImageView.kt | 48 ++++++++++--------- .../core/common/util/system/ImageUtil.kt | 15 ++++-- gradle/libs.versions.toml | 2 +- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt b/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt index 6403f760b..84e3f0496 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt @@ -10,7 +10,6 @@ import coil3.decode.ImageSource import coil3.fetch.SourceFetchResult import coil3.request.Options import coil3.request.bitmapConfig -import eu.kanade.tachiyomi.util.system.GLUtil import okio.BufferedSource import tachiyomi.core.common.util.system.ImageUtil import tachiyomi.decoder.ImageDecoder @@ -46,10 +45,7 @@ class TachiyomiImageDecoder(private val resources: ImageSource, private val opti check(bitmap != null) { "Failed to decode image" } - if ( - options.bitmapConfig == Bitmap.Config.HARDWARE && - maxOf(bitmap.width, bitmap.height) <= GLUtil.maxTextureSize - ) { + if (options.bitmapConfig == Bitmap.Config.HARDWARE && ImageUtil.canUseHardwareBitmap(bitmap)) { val hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false) if (hwBitmap != null) { bitmap.recycle() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt index bd6f419c9..5d66fc808 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt @@ -295,32 +295,34 @@ open class ReaderPageImageView @JvmOverloads constructor( isVisible = true } is BufferedSource -> { - if (!isWebtoon || !ImageUtil.canUseCoilToDecode(data)) { + if (!isWebtoon) { + setHardwareConfig(ImageUtil.canUseHardwareBitmap(data)) setImage(ImageSource.inputStream(data.inputStream())) isVisible = true - } else { - val request = ImageRequest.Builder(context) - .data(data) - .memoryCachePolicy(CachePolicy.DISABLED) - .diskCachePolicy(CachePolicy.DISABLED) - .target( - onSuccess = { result -> - val image = result as BitmapImage - setImage(ImageSource.bitmap(image.bitmap)) - isVisible = true - }, - onError = { - this@ReaderPageImageView.onImageLoadError() - }, - ) - .size(ViewSizeResolver(this@ReaderPageImageView)) - .precision(Precision.INEXACT) - .cropBorders(config.cropBorders) - .customDecoder(true) - .crossfade(false) - .build() - context.imageLoader.enqueue(request) + return@apply } + + ImageRequest.Builder(context) + .data(data) + .memoryCachePolicy(CachePolicy.DISABLED) + .diskCachePolicy(CachePolicy.DISABLED) + .target( + onSuccess = { result -> + val image = result as BitmapImage + setImage(ImageSource.bitmap(image.bitmap)) + isVisible = true + }, + onError = { + onImageLoadError() + }, + ) + .size(ViewSizeResolver(this@ReaderPageImageView)) + .precision(Precision.INEXACT) + .cropBorders(config.cropBorders) + .customDecoder(true) + .crossfade(false) + .build() + .let(context.imageLoader::enqueue) } else -> { throw IllegalArgumentException("Not implemented for class ${data::class.simpleName}") diff --git a/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt b/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt index 834c3ac63..68b49f75b 100644 --- a/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt +++ b/core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt @@ -310,9 +310,18 @@ object ImageUtil { val bottomOffset = topOffset + splitHeight } - fun canUseCoilToDecode(imageSource: BufferedSource): Boolean { - val options = extractImageOptions(imageSource) - return maxOf(options.outWidth, options.outHeight) <= GLUtil.maxTextureSize + fun canUseHardwareBitmap(bitmap: Bitmap): Boolean { + return canUseHardwareBitmap(bitmap.width, bitmap.height) + } + + fun canUseHardwareBitmap(imageSource: BufferedSource): Boolean { + return with(extractImageOptions(imageSource)) { + canUseHardwareBitmap(outWidth, outHeight) + } + } + + private fun canUseHardwareBitmap(width: Int, height: Int): Boolean { + return maxOf(width, height) <= GLUtil.maxTextureSize } /** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 397b08841..2f9b40401 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -48,7 +48,7 @@ coil-gif = { module = "io.coil-kt.coil3:coil-gif" } coil-compose = { module = "io.coil-kt.coil3:coil-compose" } coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp" } -subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:b8e1b0ed2b" +subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:66e0db195d" image-decoder = "com.github.tachiyomiorg:image-decoder:41c059e540" natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1"