blob: 31d97bdd6548519acb39e8435930667757f6bed7 [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/mac/vsync_provider_mac_impl.h"
#include "base/trace_event/trace_event.h"
#include <mach/mach_time.h>
#include <CoreVideo/CoreVideo.h>
namespace sky {
namespace services {
namespace vsync {
#define link_ (reinterpret_cast<CVDisplayLinkRef>(opaque_))
VsyncProviderMacImpl::VsyncProviderMacImpl(
mojo::InterfaceRequest<::vsync::VSyncProvider> request)
: binding_(this, request.Pass()), opaque_(nullptr), trace_level_(false) {
// Create the link.
CVDisplayLinkRef link = nullptr;
CVDisplayLinkCreateWithActiveCGDisplays(&link);
opaque_ = link;
// Set the output callback.
CVDisplayLinkSetOutputCallback(
link_,
[](CVDisplayLinkRef link, const CVTimeStamp* now,
const CVTimeStamp* output, CVOptionFlags flags_in,
CVOptionFlags* flags_out, void* context) -> CVReturn {
OnDisplayLink(context);
return kCVReturnSuccess;
},
this);
}
VsyncProviderMacImpl::~VsyncProviderMacImpl() {
CVDisplayLinkRelease(link_);
}
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;
}
void VsyncProviderMacImpl::OnDisplayLink(void* thiz) {
reinterpret_cast<VsyncProviderMacImpl*>(thiz)->OnDisplayLink();
}
void VsyncProviderMacImpl::OnDisplayLink() {
TRACE_COUNTER1("vsync", "PlatformVSync", trace_level_ = !trace_level_);
// Stop the link.
CVDisplayLinkStop(link_);
// Fire all callbacks and clear.
uint64_t micros = CurrentTimeMicroseconds();
for (const auto& callback : pending_callbacks_) {
callback.Run(micros);
}
pending_callbacks_.clear();
}
void VsyncProviderMacImpl::AwaitVSync(const AwaitVSyncCallback& callback) {
pending_callbacks_.push_back(callback);
CVDisplayLinkStart(link_);
}
} // namespace vsync
} // namespace services
} // namespace sky