Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit bc70a02

Browse files
committed
3 drawables ought to be enough for anybody
1 parent 93c217c commit bc70a02

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.mm

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)