@@ -53,6 +53,7 @@ @interface FlutterDrawable : NSObject <CAMetalDrawable> {
5353 __weak FlutterMetalLayer* _layer;
5454 NSUInteger _drawableId;
5555 IOSurface * _surface;
56+ CFTimeInterval _presentedTime;
5657}
5758
5859- (instancetype )initWithTexture : (id <MTLTexture >)texture
@@ -61,6 +62,7 @@ - (instancetype)initWithTexture:(id<MTLTexture>)texture
6162 surface : (IOSurface *)surface ;
6263
6364@property (readonly ) IOSurface * surface;
65+ @property (readwrite , nonatomic ) CFTimeInterval presentedTime;
6466
6567@end
6668
@@ -190,7 +192,7 @@ - (IOSurface*)createIOSurface {
190192 // we really need to. With triple buffering at 120Hz that results in about
191193 // 2-3 milliseconds wait time at beginning of display link callback.
192194 // With four buffers this number gets close to zero.
193- if (_totalDrawables < 4 ) {
195+ if (_totalDrawables < 3 ) {
194196 ++_totalDrawables;
195197 IOSurface * surface = [self createIOSurface ];
196198 MTLTextureDescriptor * textureDescriptor =
@@ -209,28 +211,24 @@ - (IOSurface*)createIOSurface {
209211 surface: surface];
210212 return drawable;
211213 } else {
212- FlutterDrawable* res;
213- CFTimeInterval start = CACurrentMediaTime ();
214-
215- while ( true ) {
216- for (FlutterDrawable* drawable in _availableDrawables ) {
217- if (!drawable. surface . inUse ) {
218- res = drawable ;
219- [_availableDrawables removeObject: drawable];
220- goto done;
221- }
214+ // Return first drawable that is not in use or the one that was presented
215+ // the longest time ago.
216+ FlutterDrawable* res = nil ;
217+ for (FlutterDrawable* drawable in _availableDrawables ) {
218+ if (! drawable. surface . isInUse ) {
219+ res = drawable;
220+ break ;
221+ }
222+ if (res == nil || drawable. presentedTime < res. presentedTime ) {
223+ res = drawable;
222224 }
223- usleep (10 );
224225 }
225- done:
226- CFTimeInterval duration = CACurrentMediaTime () - start;
227- if (duration > 0.003 ) {
228- NSLog (@" Getting drawable took %f " , duration);
226+ if (res != nil ) {
227+ [_availableDrawables removeObject: res];
229228 }
230229 return res;
231230 }
232231 }
233- return nil ;
234232}
235233
236234- (void )presentOnMainThread : (FlutterDrawable*)drawable {
@@ -241,6 +239,7 @@ - (void)presentOnMainThread:(FlutterDrawable*)drawable {
241239 [CATransaction begin ];
242240 [CATransaction setDisableActions: YES ];
243241 self.contents = drawable.surface ;
242+ drawable.presentedTime = CACurrentMediaTime ();
244243 [CATransaction commit ];
245244 _displayLink.paused = NO ;
246245 _displayLinkPauseCountdown = 0 ;
@@ -268,6 +267,8 @@ - (void)presentDrawable:(FlutterDrawable*)drawable {
268267
269268@implementation FlutterDrawable
270269
270+ @synthesize presentedTime = _presentedTime;
271+
271272- (instancetype )initWithTexture : (id <MTLTexture >)texture
272273 layer : (FlutterMetalLayer*)layer
273274 drawableId : (NSUInteger )drawableId
@@ -292,10 +293,6 @@ - (CAMetalLayer*)layer {
292293}
293294#pragma clang diagnostic pop
294295
295- - (CFTimeInterval)presentedTime {
296- return 0 ;
297- }
298-
299296- (NSUInteger )drawableID {
300297 return self->_drawableId ;
301298}
0 commit comments