Skip to content

Commit

Permalink
Added functionality to display partial images instead of placeholder …
Browse files Browse the repository at this point in the history
…if in cache

Reviewed By: kartavya-ramnani

Differential Revision: D58424402

fbshipit-source-id: de4434e90c7c785ca7317b36033ac9b308652644
  • Loading branch information
oprisnik authored and facebook-github-bot committed Jun 19, 2024
1 parent f2a301f commit fe33125
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,24 @@ class KFrescoController(

// Check if the image is in cache
val cachedImage = vitoImagePipeline.getCachedImage(imageRequest)
if (drawable.setActualImage(imageRequest, cachedImage)) {

val isIntermediateImage =
config.useIntermediateImagesAsPlaceholder() &&
cachedImage?.get()?.qualityInfo?.isOfFullQuality != true
val hasImage = drawable.setActualImage(imageRequest, cachedImage, isIntermediateImage)
if (hasImage && !isIntermediateImage) {
// Immediately return since we have the full image
return true
}

// The image is not in cache -> Set up layers visible until the image is available
drawable.placeholderLayer.setPlaceholder(imageRequest.resources, options)
drawable.listenerManager.onPlaceholderSet(
imageId, imageRequest, drawable.placeholderLayer.getDataModel().maybeGetDrawable())
if (!hasImage) {
// The image is not in cache -> Set up layers visible until the image is available
drawable.placeholderLayer.setPlaceholder(imageRequest.resources, options)
drawable.listenerManager.onPlaceholderSet(
imageId, imageRequest, drawable.placeholderLayer.getDataModel().maybeGetDrawable())

drawable.setupProgressLayer(imageRequest.resources, options)
drawable.setupProgressLayer(imageRequest.resources, options)
}

// Fetch the image
lightweightBackgroundThreadExecutor.execute {
Expand Down Expand Up @@ -243,7 +251,8 @@ class KFrescoController(
*/
private fun KFrescoVitoDrawable.setActualImage(
imageRequest: VitoImageRequest,
imageReference: CloseableReference<CloseableImage>?
imageReference: CloseableReference<CloseableImage>?,
isIntermediateImage: Boolean = false,
): Boolean {
traceSection("KFrescoController#setActualImage") {
try {
Expand All @@ -258,13 +267,17 @@ class KFrescoController(
// TODO(T105148151): trigger listeners
invalidateSelf()
val imageInfo = image.imageInfo
listenerManager.onFinalImageSet(
imageId,
imageRequest,
ImageOrigin.MEMORY_BITMAP_SHORTCUT,
imageInfo,
obtainExtras(null, imageReference),
actualImageDrawable)
if (isIntermediateImage) {
listenerManager.onIntermediateImageSet(imageId, imageRequest, imageInfo)
} else {
listenerManager.onFinalImageSet(
imageId,
imageRequest,
ImageOrigin.MEMORY_BITMAP_SHORTCUT,
imageInfo,
obtainExtras(null, imageReference),
actualImageDrawable)
}
debugOverlayHandler?.update(this)
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.fresco.vito.core.impl

import android.graphics.Bitmap
Expand Down Expand Up @@ -185,26 +186,37 @@ open class FrescoController2Impl(

// Check if the image is in cache
val cachedImage = mImagePipeline.getCachedImage(imageRequest)
var needsPlaceholderDrawable = true
try {
if (CloseableReference.isValid(cachedImage)) {
frescoDrawable.imageOrigin = ImageOrigin.MEMORY_BITMAP_SHORTCUT
val isIntermediateImage =
mConfig.useIntermediateImagesAsPlaceholder() &&
cachedImage?.get()?.qualityInfo?.isOfFullQuality != true
// Immediately display the actual image.
setActualImage(frescoDrawable, imageRequest, cachedImage, true, null)
setActualImage(frescoDrawable, imageRequest, cachedImage, true, null, isIntermediateImage)
frescoDrawable.setFetchSubmitted(true)
mDebugOverlayFactory.update(frescoDrawable, extras)
return true
if (!isIntermediateImage) {
return true
} else {
// We are displaying an intermediate image and can skip setting up the placeholder
needsPlaceholderDrawable = false
}
}
} finally {
CloseableReference.closeSafely(cachedImage)
}

// The image is not in cache -> Set up layers visible until the image is available
frescoDrawable.setProgressDrawable(
mHierarcher.buildProgressDrawable(imageRequest.resources, imageRequest.imageOptions))
// Immediately show the progress image and set progress to 0
frescoDrawable.setProgress(0f)
frescoDrawable.showProgressImmediately()
setUpPlaceholder(frescoDrawable, imageRequest, imageId)
if (!needsPlaceholderDrawable) {
// The image is not in cache -> Set up layers visible until the image is available
frescoDrawable.setProgressDrawable(
mHierarcher.buildProgressDrawable(imageRequest.resources, imageRequest.imageOptions))
// Immediately show the progress image and set progress to 0
frescoDrawable.setProgress(0f)
frescoDrawable.showProgressImmediately()
setUpPlaceholder(frescoDrawable, imageRequest, imageId)
}

// Fetch the image
val fetchRunnable = Runnable {
Expand Down Expand Up @@ -286,8 +298,9 @@ open class FrescoController2Impl(
drawable: FrescoDrawable2Impl,
imageRequest: VitoImageRequest,
image: CloseableReference<CloseableImage>?,
isImmediate: Boolean,
dataSource: DataSource<CloseableReference<CloseableImage>>?
displayImmediately: Boolean,
dataSource: DataSource<CloseableReference<CloseableImage>>?,
isIntermediateImage: Boolean = false,
) {
val actualImageWrapperDrawable = drawable.actualImageWrapper
mHierarcher.setupActualImageWrapper(
Expand All @@ -297,7 +310,7 @@ open class FrescoController2Impl(
imageRequest.resources, imageRequest.imageOptions, image!!)
actualImageWrapperDrawable.setCurrent(actualDrawable ?: NopDrawable)
drawable.setImage(actualImageWrapperDrawable, image)
if (isImmediate || imageRequest.imageOptions.fadeDurationMs <= 0) {
if (displayImmediately || imageRequest.imageOptions.fadeDurationMs <= 0) {
drawable.showImageImmediately()
} else {
drawable.fadeInImage(imageRequest.imageOptions.fadeDurationMs)
Expand All @@ -307,13 +320,13 @@ open class FrescoController2Impl(
}
val extras = obtainExtras(dataSource, image, drawable)
val imageInfo = image.get().imageInfo
if (notifyFinalResult(dataSource)) {
if (!isIntermediateImage && notifyFinalResult(dataSource)) {
drawable.internalListener.onFinalImageSet(
drawable.imageId, imageRequest, drawable.imageOrigin, imageInfo, extras, actualDrawable)
} else {
drawable.internalListener.onIntermediateImageSet(drawable.imageId, imageRequest, imageInfo)
}
drawable.imagePerfListener.onImageSuccess(drawable, isImmediate)
drawable.imagePerfListener.onImageSuccess(drawable, displayImmediately)
var progress = 1f
if (dataSource != null && !dataSource.isFinished) {
progress = dataSource.progress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ constructor(override val prefetchConfig: PrefetchConfig = DefaultPrefetchConfig(

override fun handleImageResultInBackground(): Boolean = false

override fun useIntermediateImagesAsPlaceholder(): Boolean = false

open class DefaultPrefetchConfig : PrefetchConfig {
override fun prefetchInOnPrepare(): Boolean = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ interface FrescoVitoConfig {
fun enableWindowWideColorGamut(): Boolean

fun handleImageResultInBackground(): Boolean

fun useIntermediateImagesAsPlaceholder(): Boolean
}

0 comments on commit fe33125

Please sign in to comment.