Add support for disabling progressive image rendering

Differential Revision: https://phabricator.pinadmin.com/D89742
This commit is contained in:
Garrett Moon 2016-05-09 15:00:44 -07:00
parent 62a853b3e9
commit c0eb6cac09
4 changed files with 92 additions and 26 deletions

View File

@ -117,6 +117,12 @@ typedef NS_ENUM(NSUInteger, ASMultiplexImageNodeErrorCode) {
*/ */
@property (nullable, nonatomic, readonly) ASImageIdentifier displayedImageIdentifier; @property (nullable, nonatomic, readonly) ASImageIdentifier displayedImageIdentifier;
/**
* @abstract If the downloader implements progressive image rendering and this value is YES progressive renders of the
* image will be displayed as the image downloads. Defaults to YES.
*/
@property (nonatomic, assign, readwrite) BOOL shouldRenderProgressImages;
#if TARGET_OS_IOS #if TARGET_OS_IOS
/** /**
* @abstract The image manager that this image node should use when requesting images from the Photos framework. If this is `nil` (the default), then `PHImageManager.defaultManager` is used. * @abstract The image manager that this image node should use when requesting images from the Photos framework. If this is `nil` (the default), then `PHImageManager.defaultManager` is used.

View File

@ -85,6 +85,10 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
ASDN::RecursiveMutex _downloadIdentifierLock; ASDN::RecursiveMutex _downloadIdentifierLock;
id _downloadIdentifier; id _downloadIdentifier;
// Properties
ASDN::RecursiveMutex _propertyLock;
BOOL _shouldRenderProgressImages;
//set on init only //set on init only
BOOL _downloaderSupportsNewProtocol; BOOL _downloaderSupportsNewProtocol;
BOOL _downloaderImplementsSetProgress; BOOL _downloaderImplementsSetProgress;
@ -186,6 +190,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
_cacheSupportsNewProtocol = [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)]; _cacheSupportsNewProtocol = [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)];
_cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)]; _cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)];
_shouldRenderProgressImages = YES;
self.shouldBypassEnsureDisplay = YES; self.shouldBypassEnsureDisplay = YES;
return self; return self;
@ -339,6 +345,27 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
#endif #endif
} }
- (void)setShouldRenderProgressImages:(BOOL)shouldRenderProgressImages
{
ASDN::MutexLocker l(_propertyLock);
if (shouldRenderProgressImages == _shouldRenderProgressImages) {
return;
}
_shouldRenderProgressImages = shouldRenderProgressImages;
ASDN::MutexUnlocker u(_propertyLock);
[self _updateProgressImageBlockOnDownloaderIfNeeded];
}
- (BOOL)shouldRenderProgressImages
{
ASDN::MutexLocker l(_propertyLock);
return _shouldRenderProgressImages;
}
#pragma mark - #pragma mark -
#pragma mark - #pragma mark -
@ -458,6 +485,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
*/ */
- (void)_updateProgressImageBlockOnDownloaderIfNeeded - (void)_updateProgressImageBlockOnDownloaderIfNeeded
{ {
BOOL shouldRenderProgressImages = self.shouldRenderProgressImages;
// Read our interface state before locking so that we don't lock super while holding our lock. // Read our interface state before locking so that we don't lock super while holding our lock.
ASInterfaceState interfaceState = self.interfaceState; ASInterfaceState interfaceState = self.interfaceState;
ASDN::MutexLocker l(_downloadIdentifierLock); ASDN::MutexLocker l(_downloadIdentifierLock);
@ -467,7 +496,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
} }
ASImageDownloaderProgressImage progress = nil; ASImageDownloaderProgressImage progress = nil;
if (ASInterfaceStateIncludesVisible(interfaceState)) { if (shouldRenderProgressImages && ASInterfaceStateIncludesVisible(interfaceState)) {
__weak __typeof__(self) weakSelf = self; __weak __typeof__(self) weakSelf = self;
progress = ^(UIImage * _Nonnull progressImage, CGFloat progress, id _Nullable downloadIdentifier) { progress = ^(UIImage * _Nonnull progressImage, CGFloat progress, id _Nullable downloadIdentifier) {
__typeof__(self) strongSelf = weakSelf; __typeof__(self) strongSelf = weakSelf;

View File

@ -73,6 +73,12 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@property (nonatomic, assign, readwrite) BOOL shouldCacheImage; @property (nonatomic, assign, readwrite) BOOL shouldCacheImage;
/**
* If the downloader implements progressive image rendering and this value is YES progressive renders of the
* image will be displayed as the image downloads. Defaults to YES.
*/
@property (nonatomic, assign, readwrite) BOOL shouldRenderProgressImages;
/** /**
* The image quality of the current image. This is a number between 0 and 1 and can be used to track * The image quality of the current image. This is a number between 0 and 1 and can be used to track
* progressive progress. Calculated by dividing number of bytes / expected number of total bytes. * progressive progress. Calculated by dividing number of bytes / expected number of total bytes.

View File

@ -46,6 +46,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
BOOL _delegateSupportsDidFailWithError; BOOL _delegateSupportsDidFailWithError;
BOOL _delegateSupportsImageNodeDidFinishDecoding; BOOL _delegateSupportsImageNodeDidFinishDecoding;
BOOL _shouldRenderProgressImages;
//set on init only //set on init only
BOOL _downloaderSupportsNewProtocol; BOOL _downloaderSupportsNewProtocol;
BOOL _downloaderImplementsSetProgress; BOOL _downloaderImplementsSetProgress;
@ -83,6 +85,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
_cacheSupportsSynchronousFetch = [cache respondsToSelector:@selector(synchronouslyFetchedCachedImageWithURL:)]; _cacheSupportsSynchronousFetch = [cache respondsToSelector:@selector(synchronouslyFetchedCachedImageWithURL:)];
_shouldCacheImage = YES; _shouldCacheImage = YES;
_shouldRenderProgressImages = YES;
self.shouldBypassEnsureDisplay = YES; self.shouldBypassEnsureDisplay = YES;
return self; return self;
@ -218,6 +221,26 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
return _delegate; return _delegate;
} }
- (void)setShouldRenderProgressImages:(BOOL)shouldRenderProgressImages
{
ASDN::MutexLocker l(_lock);
if (shouldRenderProgressImages == _shouldRenderProgressImages) {
return;
}
_shouldRenderProgressImages = shouldRenderProgressImages;
ASDN::MutexUnlocker u(_lock);
[self _updateProgressImageBlockOnDownloaderIfNeeded];
}
- (BOOL)shouldRenderProgressImages
{
ASDN::MutexLocker l(_lock);
return _shouldRenderProgressImages;
}
- (BOOL)placeholderShouldPersist - (BOOL)placeholderShouldPersist
{ {
ASDN::MutexLocker l(_lock); ASDN::MutexLocker l(_lock);
@ -309,6 +332,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
*/ */
- (void)_updateProgressImageBlockOnDownloaderIfNeeded - (void)_updateProgressImageBlockOnDownloaderIfNeeded
{ {
BOOL shouldRenderProgressImages = self.shouldRenderProgressImages;
// Read our interface state before locking so that we don't lock super while holding our lock. // Read our interface state before locking so that we don't lock super while holding our lock.
ASInterfaceState interfaceState = self.interfaceState; ASInterfaceState interfaceState = self.interfaceState;
ASDN::MutexLocker l(_lock); ASDN::MutexLocker l(_lock);
@ -318,7 +343,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
} }
ASImageDownloaderProgressImage progress = nil; ASImageDownloaderProgressImage progress = nil;
if (ASInterfaceStateIncludesVisible(interfaceState)) { if (shouldRenderProgressImages && ASInterfaceStateIncludesVisible(interfaceState)) {
__weak __typeof__(self) weakSelf = self; __weak __typeof__(self) weakSelf = self;
progress = ^(UIImage * _Nonnull progressImage, CGFloat progress, id _Nullable downloadIdentifier) { progress = ^(UIImage * _Nonnull progressImage, CGFloat progress, id _Nullable downloadIdentifier) {
__typeof__(self) strongSelf = weakSelf; __typeof__(self) strongSelf = weakSelf;