Flutter Engine
The Flutter Engine
Classes | Functions
FlutterDisplayLinkTest.mm File Reference
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDisplayLink.h"
#import <AppKit/AppKit.h>
#include <numeric>
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/testing/testing.h"

Go to the source code of this file.

Classes

class  TestDisplayLinkDelegate
 

Functions

 TEST (FlutterDisplayLinkTest, ViewAddedToWindowFirst)
 
 TEST (FlutterDisplayLinkTest, ViewAddedToWindowLater)
 
 TEST (FlutterDisplayLinkTest, ViewRemovedFromWindow)
 
 TEST (FlutterDisplayLinkTest, WorkaroundForFB13482573)
 
 TEST (FlutterDisplayLinkTest, CVDisplayLinkInterval)
 

Function Documentation

◆ TEST() [1/5]

TEST ( FlutterDisplayLinkTest  ,
CVDisplayLinkInterval   
)

Definition at line 153 of file FlutterDisplayLinkTest.mm.

153 {
154 CVDisplayLinkRef link;
155 CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(), &link);
156 __block CFTimeInterval last = 0;
157 auto intervals = std::make_shared<std::vector<CFTimeInterval>>();
158 auto event = std::make_shared<fml::AutoResetWaitableEvent>();
159 CVDisplayLinkSetOutputHandler(
160 link, ^(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow,
161 const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut) {
162 if (last != 0) {
163 intervals->push_back(CACurrentMediaTime() - last);
164 }
165 last = CACurrentMediaTime();
166 if (intervals->size() == 10) {
167 event->Signal();
168 }
169 return 0;
170 });
171
172 CVDisplayLinkStart(link);
173 event->Wait();
174 CVDisplayLinkStop(link);
175 CVDisplayLinkRelease(link);
176 CFTimeInterval average = std::reduce(intervals->begin(), intervals->end()) / intervals->size();
177 CFTimeInterval max = *std::max_element(intervals->begin(), intervals->end());
178 CFTimeInterval min = *std::min_element(intervals->begin(), intervals->end());
179 NSLog(@"CVDisplayLink Interval: Average: %fs, Max: %fs, Min: %fs", average, max, min);
180}
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
def link(from_root, to_root)
Definition: dart_pkg.py:44

◆ TEST() [2/5]

TEST ( FlutterDisplayLinkTest  ,
ViewAddedToWindowFirst   
)

Definition at line 36 of file FlutterDisplayLinkTest.mm.

36 {
37 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
38 styleMask:NSWindowStyleMaskTitled
39 backing:NSBackingStoreNonretained
40 defer:NO];
41 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
42 [window setContentView:view];
43
44 auto event = std::make_shared<fml::AutoResetWaitableEvent>();
45
47 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
48 event->Signal();
49 }];
50
51 FlutterDisplayLink* displayLink = [FlutterDisplayLink displayLinkWithView:view];
52 displayLink.delegate = delegate;
53 displayLink.paused = NO;
54
55 event->Wait();
56
57 [displayLink invalidate];
58}
GLFWwindow * window
Definition: main.cc:45
FlKeyEvent * event
instancetype initWithFrame
Definition: ascii_trie.cc:9
Definition: ref_ptr.h:256

◆ TEST() [3/5]

TEST ( FlutterDisplayLinkTest  ,
ViewAddedToWindowLater   
)

Definition at line 60 of file FlutterDisplayLinkTest.mm.

60 {
61 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
62
63 auto event = std::make_shared<fml::AutoResetWaitableEvent>();
64
66 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
67 event->Signal();
68 }];
69
70 FlutterDisplayLink* displayLink = [FlutterDisplayLink displayLinkWithView:view];
71 displayLink.delegate = delegate;
72 displayLink.paused = NO;
73
74 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
75 styleMask:NSWindowStyleMaskTitled
76 backing:NSBackingStoreNonretained
77 defer:NO];
78 [window setContentView:view];
79
80 event->Wait();
81
82 [displayLink invalidate];
83}

◆ TEST() [4/5]

TEST ( FlutterDisplayLinkTest  ,
ViewRemovedFromWindow   
)

Definition at line 85 of file FlutterDisplayLinkTest.mm.

85 {
86 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
87 styleMask:NSWindowStyleMaskTitled
88 backing:NSBackingStoreNonretained
89 defer:NO];
90 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
91 [window setContentView:view];
92
93 auto event = std::make_shared<fml::AutoResetWaitableEvent>();
94
96 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
97 event->Signal();
98 }];
99
100 FlutterDisplayLink* displayLink = [FlutterDisplayLink displayLinkWithView:view];
101 displayLink.delegate = delegate;
102 displayLink.paused = NO;
103
104 event->Wait();
105 displayLink.paused = YES;
106
107 event->Reset();
108
109 displayLink.paused = NO;
110
111 [window setContentView:nil];
112
113 EXPECT_TRUE(event->WaitWithTimeout(fml::TimeDelta::FromMilliseconds(100)));
114 EXPECT_FALSE(event->IsSignaledForTest());
115
116 [displayLink invalidate];
117}
static constexpr TimeDelta FromMilliseconds(int64_t millis)
Definition: time_delta.h:46
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678

◆ TEST() [5/5]

TEST ( FlutterDisplayLinkTest  ,
WorkaroundForFB13482573   
)

Definition at line 119 of file FlutterDisplayLinkTest.mm.

119 {
120 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
121 styleMask:NSWindowStyleMaskTitled
122 backing:NSBackingStoreNonretained
123 defer:NO];
124 NSView* view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
125 [window setContentView:view];
126
127 auto event = std::make_shared<fml::AutoResetWaitableEvent>();
128
130 initWithBlock:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp) {
131 event->Signal();
132 }];
133
134 FlutterDisplayLink* displayLink = [FlutterDisplayLink displayLinkWithView:view];
135 displayLink.delegate = delegate;
136 displayLink.paused = NO;
137
138 event->Wait();
139 displayLink.paused = YES;
140
141 event->Reset();
142 [NSThread detachNewThreadWithBlock:^{
143 // Here pthread_self() will be same as pthread_self inside first invocation of
144 // display link callback, causing CVDisplayLinkStart to return error.
145 displayLink.paused = NO;
146 }];
147
148 event->Wait();
149
150 [displayLink invalidate];
151}