8 #import <AppKit/AppKit.h>
11 #include "flutter/fml/synchronization/waitable_event.h"
12 #include "flutter/testing/testing.h"
15 void (^
_block)(CFTimeInterval timestamp, CFTimeInterval targetTimestamp);
18 - (instancetype)initWithBlock:(
void (^)(CFTimeInterval timestamp,
19 CFTimeInterval targetTimestamp))block;
24 - (instancetype)initWithBlock:(
void (^__strong)(CFTimeInterval, CFTimeInterval))block {
25 if (
self = [super init]) {
31 - (void)onDisplayLink:(CFTimeInterval)timestamp targetTimestamp:(CFTimeInterval)targetTimestamp {
32 _block(timestamp, targetTimestamp);
43 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
44 styleMask:NSWindowStyleMaskTitled
45 backing:NSBackingStoreNonretained
47 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
48 [window setContentView:view];
50 __block BOOL signalled = NO;
53 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
69 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
71 __block BOOL signalled = NO;
74 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
82 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
83 styleMask:NSWindowStyleMaskTitled
84 backing:NSBackingStoreNonretained
86 [window setContentView:view];
96 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
97 styleMask:NSWindowStyleMaskTitled
98 backing:NSBackingStoreNonretained
100 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
101 [window setContentView:view];
103 __block BOOL signalled = NO;
106 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
123 [window setContentView:nil];
125 CFTimeInterval start = CACurrentMediaTime();
126 while (CACurrentMediaTime() < start + 0.1) {
130 EXPECT_FALSE(signalled);
136 CVDisplayLinkRef link;
137 CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(), &link);
138 __block CFTimeInterval last = 0;
139 auto intervals = std::make_shared<std::vector<CFTimeInterval>>();
140 auto event = std::make_shared<fml::AutoResetWaitableEvent>();
141 CVDisplayLinkSetOutputHandler(
142 link, ^(CVDisplayLinkRef displayLink,
const CVTimeStamp* inNow,
143 const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut) {
145 intervals->push_back(CACurrentMediaTime() - last);
147 last = CACurrentMediaTime();
148 if (intervals->size() == 10) {
154 CVDisplayLinkStart(link);
156 CVDisplayLinkStop(link);
157 CVDisplayLinkRelease(link);
158 CFTimeInterval average = std::reduce(intervals->begin(), intervals->end()) / intervals->size();
159 CFTimeInterval max = *std::max_element(intervals->begin(), intervals->end());
160 CFTimeInterval min = *std::min_element(intervals->begin(), intervals->end());
161 NSLog(
@"CVDisplayLink Interval: Average: %fs, Max: %fs, Min: %fs", average, max, min);
TEST_F(FlutterDisplayLinkTest, ViewAddedToWindowFirst)
void invalidate()
Invalidates the display link.
BOOL paused
Pauses and resumes the display link.
id< FlutterDisplayLinkDelegate > delegate
instancetype displayLinkWithView:(NSView *view)
void ensureMainLoopInitialized()
void pollFlutterMessagesOnce()
void(^ _block)(CFTimeInterval timestamp, CFTimeInterval targetTimestamp)