blob: f425755ad6c58905276c854ebd6b94ebf2045e38 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/services/vsync/ios/vsync_provider_ios_impl.h"
#include "base/trace_event/trace_event.h"
#include <Foundation/Foundation.h>
#include <QuartzCore/CADisplayLink.h>
#include <mach/mach_time.h>
#include <vector>
@interface VSyncClient : NSObject
@end
static inline uint64_t CurrentTimeMicroseconds() {
static mach_timebase_info_data_t timebase = {0};
if (timebase.denom == 0) {
(void)mach_timebase_info(&timebase);
}
return (mach_absolute_time() * 1e-3 * timebase.numer) / timebase.denom;
}
@implementation VSyncClient {
CADisplayLink* _displayLink;
std::vector<::vsync::VSyncProvider::AwaitVSyncCallback> _pendingCallbacks;
BOOL _traceLevel;
}
- (instancetype)init {
self = [super init];
if (self) {
_displayLink = [[CADisplayLink
displayLinkWithTarget:self
selector:@selector(onDisplayLink:)] retain];
_displayLink.paused = YES;
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
}
return self;
}
- (void)await:(::vsync::VSyncProvider::AwaitVSyncCallback)callback {
_pendingCallbacks.push_back(callback);
_displayLink.paused = NO;
}
- (void)onDisplayLink:(CADisplayLink*)link {
TRACE_COUNTER1("vsync", "PlatformVSync", _traceLevel = !_traceLevel);
_displayLink.paused = YES;
uint64_t micros = CurrentTimeMicroseconds();
for (const auto& callback : _pendingCallbacks) {
callback.Run(micros);
}
_pendingCallbacks.clear();
}
- (void)dealloc {
[_displayLink invalidate];
[_displayLink release];
[super dealloc];
}
@end
namespace sky {
namespace services {
namespace vsync {
VsyncProviderIOSImpl::VsyncProviderIOSImpl(
mojo::InterfaceRequest<::vsync::VSyncProvider> request)
: binding_(this, request.Pass()), client_([[VSyncClient alloc] init]) {}
VsyncProviderIOSImpl::~VsyncProviderIOSImpl() {
[client_ release];
}
void VsyncProviderIOSImpl::AwaitVSync(const AwaitVSyncCallback& callback) {
[client_ await:callback];
}
} // namespace vsync
} // namespace services
} // namespace sky