fix: Switch to hardware bitmap in reader only if device can handle it

This commit is contained in:
AntsyLich 2024-11-20 21:20:00 +07:00 committed by Ahmad Ansori Palembani
parent fbe2d8c701
commit 01fcd7d122
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
4 changed files with 50 additions and 56 deletions

View file

@ -50,7 +50,7 @@ class TachiyomiImageDecoder(private val resources: ImageSource, private val opti
if ( if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
options.bitmapConfig == Bitmap.Config.HARDWARE && options.bitmapConfig == Bitmap.Config.HARDWARE &&
maxOf(bitmap.width, bitmap.height) <= GLUtil.maxTextureSize !ImageUtil.isMaxTextureSizeExceeded(bitmap)
) { ) {
val hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false) val hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false)
if (hwBitmap != null) { if (hwBitmap != null) {

View file

@ -18,6 +18,7 @@ import androidx.annotation.CallSuper
import androidx.annotation.StyleRes import androidx.annotation.StyleRes
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import coil3.BitmapImage
import coil3.asDrawable import coil3.asDrawable
import coil3.dispose import coil3.dispose
import coil3.imageLoader import coil3.imageLoader
@ -225,20 +226,26 @@ open class ReaderPageImageView @JvmOverloads constructor(
}, },
) )
val useCoilPipeline = if (isWebtoon) { when (data) {
try { !ImageUtil.isMaxTextureSizeExceeded(data) } catch (_: IllegalStateException) { false } is BitmapDrawable -> {
} else { setImage(ImageSource.bitmap(data.bitmap))
false isVisible = true
}
is BufferedSource -> {
if (!isWebtoon || !ImageUtil.isMaxTextureSizeExceeded(data)) {
setHardwareConfig(!ImageUtil.isMaxTextureSizeExceeded(data))
setImage(ImageSource.inputStream(data.inputStream()))
isVisible = true
return@apply
} }
if (useCoilPipeline) { ImageRequest.Builder(context)
val request = ImageRequest.Builder(context)
.data(data) .data(data)
.memoryCachePolicy(CachePolicy.DISABLED) .memoryCachePolicy(CachePolicy.DISABLED)
.diskCachePolicy(CachePolicy.DISABLED) .diskCachePolicy(CachePolicy.DISABLED)
.target( .target(
onSuccess = { result -> onSuccess = { result ->
val image = result.asDrawable(context.resources) as BitmapDrawable val image = result as BitmapImage
setImage(ImageSource.bitmap(image.bitmap)) setImage(ImageSource.bitmap(image.bitmap))
isVisible = true isVisible = true
}, },
@ -252,14 +259,11 @@ open class ReaderPageImageView @JvmOverloads constructor(
.customDecoder(true) .customDecoder(true)
.crossfade(false) .crossfade(false)
.build() .build()
context.imageLoader.enqueue(request) .let(context.imageLoader::enqueue)
} else { }
when (data) { else -> {
is BitmapDrawable -> setImage(ImageSource.bitmap(data.bitmap)) throw IllegalArgumentException("Not implemented for class ${data::class.simpleName}")
is BufferedSource -> setImage(ImageSource.inputStream(data.inputStream()))
else -> throw IllegalArgumentException("Not implemented for class ${data::class.simpleName}")
} }
isVisible = true
} }
} }

View file

@ -776,27 +776,17 @@ object ImageUtil {
return options return options
} }
fun isMaxTextureSizeExceeded(data: Any): Boolean { fun isMaxTextureSizeExceeded(source: BufferedSource): Boolean =
val width: Int extractImageOptions(source).let { opts -> isMaxTextureSizeExceeded(opts.outWidth, opts.outHeight) }
val height: Int
when (data) {
is BufferedSource -> {
val opts = extractImageOptions(data)
width = opts.outWidth
height = opts.outHeight
}
is BitmapDrawable -> {
width = data.bitmap.width
height = data.bitmap.height
}
is Bitmap -> {
width = data.width
height = data.height
}
else -> throw IllegalArgumentException("Not implemented for class ${data::class.simpleName}")
}
if (minOf(width, height) <= 0) throw IllegalStateException("Invalid bitmap size") fun isMaxTextureSizeExceeded(drawable: BitmapDrawable): Boolean =
isMaxTextureSizeExceeded(drawable.bitmap)
fun isMaxTextureSizeExceeded(bitmap: Bitmap): Boolean =
isMaxTextureSizeExceeded(data.width, data.height)
private fun isMaxTextureSizeExceeded(width: Int, height: Int): Boolean {
if (minOf(width, height) <= 0) return false
return maxOf(width, height) > GLUtil.maxTextureSize return maxOf(width, height) > GLUtil.maxTextureSize
} }

View file

@ -89,7 +89,7 @@ sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", ver
sqldelight-android-paging = { module = "app.cash.sqldelight:androidx-paging3-extensions", version.ref = "sqldelight" } sqldelight-android-paging = { module = "app.cash.sqldelight:androidx-paging3-extensions", version.ref = "sqldelight" }
sqldelight-dialects-sql = { module = "app.cash.sqldelight:sqlite-3-38-dialect", version.ref = "sqldelight" } sqldelight-dialects-sql = { module = "app.cash.sqldelight:sqlite-3-38-dialect", version.ref = "sqldelight" }
subsamplingscaleimageview = { module = "com.github.null2264:subsampling-scale-image-view", version = "338caedb5f" } subsamplingscaleimageview = { module = "com.github.null2264:subsampling-scale-image-view", version = "f7b674ebdd" }
shizuku-api = { module = "dev.rikka.shizuku:api", version.ref = "shizuku" } shizuku-api = { module = "dev.rikka.shizuku:api", version.ref = "shizuku" }
shizuku-provider = { module = "dev.rikka.shizuku:provider", version.ref = "shizuku" } shizuku-provider = { module = "dev.rikka.shizuku:provider", version.ref = "shizuku" }
taptargetview = { module = "com.getkeepsafe.taptargetview:taptargetview", version = "1.13.3" } taptargetview = { module = "com.getkeepsafe.taptargetview:taptargetview", version = "1.13.3" }