一间杂货铺~

10月 13

iOS中FPS的测量及其色彩表示


I. FPS的测量

对于FPS的测量,就是使用CADisplayLink计算某个时间段内某个方法的调用次数:

FPS = 调用次数 / 时间

#import <UIKit/UIKit.h>

@interface FPSMeasurer : NSObject
+ (FPSMeasurer *)sharedFPSMeasurer;
@property (nonatomic, getter=isPaused) BOOL paused;
@property (nonatomic, assign) NSTimeInterval reportInterval;// default is 1, >= 0.1
@property (nonatomic, copy) void (^reportBlock)(int fps, UIColor *fpsColor);
@end
#import "FPSMeasurer.h"
#import <QuartzCore/QuartzCore.h>

@implementation FPSMeasurer {
    CADisplayLink *_displayLink;
    NSTimeInterval _lastTimestamp;
    int _frames;
}

static FPSMeasurer *sharedFPSMeasurer = nil;

+ (FPSMeasurer *)sharedFPSMeasurer {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedFPSMeasurer = [[super allocWithZone:NULL] init];

        sharedFPSMeasurer->_reportInterval = 1;

        CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:sharedFPSMeasurer selector:@selector(displayLinkSelector:)];
        [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        sharedFPSMeasurer->_displayLink = displayLink;
    });
    return sharedFPSMeasurer;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [FPSMeasurer sharedFPSMeasurer];
}

- (void)displayLinkSelector:(CADisplayLink *)displayLink {
    ++_frames;
    if (_lastTimestamp < DBL_EPSILON) {
        _lastTimestamp = displayLink.timestamp;
    } else {
        NSTimeInterval time = displayLink.timestamp - _lastTimestamp;
        if (time > self.reportInterval) {
            int fps = (int)(_frames / time);
            _frames = 0;
            _lastTimestamp = displayLink.timestamp;
            if (self.reportBlock) {
                self.reportBlock(fps, [UIColor colorWithHue:fps / 180.0 saturation:1 brightness:1 alpha:1]);
            }
        }
    }
}

- (void)setReportInterval:(NSTimeInterval)reportInterval {
    if (_reportInterval != reportInterval) {
        if ([NSThread currentThread]) {
            _reportInterval = reportInterval > 0.1 ? reportInterval : 0.1;
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                _reportInterval = reportInterval > 0.1 ? reportInterval : 0.1;
            });
        }
    }
}

- (void)setPaused:(BOOL)paused {
    if (_paused != paused) {
        if ([NSThread currentThread]) {
            self->_displayLink.paused = paused;
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                self->_displayLink.paused = paused;
            });
        }
    }
}

@end

II. FPS的色彩表示

在用颜色展现FPS的高低时,通常是红色表示低帧率绿色表示高帧率;橙色、黄色、黄绿色,表示高低之间的帧率。

为了将帧率转化为相应的颜色,最简单的方式就是使用HSBHSL色彩空间。

在这两个色彩空间中,H都是色相,它的取值范围是360°的圆心角。360°对应红色60°对应黄色120°对应绿色

在将帧率转化为颜色时,只需要改变H即可。

iOS中,苹果提供了HSB色彩空间所对应的方法,HSB取值被限制在[0, 1.0]区间内。

iOS 10之后(含iOS 10),不会对HSB的取值进行限制,对于[0, 1]区间外的值,会使用扩展的色彩空间

因此,在将帧率转化为颜色时,H的值可以用FPS / 60.0 * 120.0 / 360.0进行计算,也就是FPS / 180.0SB固定为1.0(也可以固定为与1.0非常相近的值)。

[UIColor colorWithHue:FPS / 180.0 saturation:1 brightness:1 alpha:1]

由于HSLHSB有一些区别,如果使用的是HSLL需要取值0.5(也可以取与0.5非常相近的值)。

标签:fps

还不快抢沙发

添加新评论