Reland "Minimal iOS app: Perform present subsequent to flush"

This is a reland of 4e385e21a4

Original change's description:
> Minimal iOS app: Perform present subsequent to flush
> 
> Currently the backbuffer present is not on the same MTLCommandQueue
> as the flush from Skia, which probably means that it's happening
> concurrently. This can overwhelm the GPU. This CL submits the present
> to the same queue as the flush.
> 
> Change-Id: Ibaf805553931c9dc46368b362a2391425ae3e60e
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248557
> Reviewed-by: Hal Canary <halcanary@skia.org>
> Commit-Queue: Jim Van Verth <jvanverth@google.com>

Change-Id: I118047630b8936838d5da8ef4307ad5c5e8d2ade
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248562
Reviewed-by: Hal Canary <halcanary@skia.org>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2019-10-14 13:42:57 -04:00 committed by Skia Commit-Bot
parent 63acfe3dd6
commit c910602376
6 changed files with 26 additions and 9 deletions

View File

@ -44,6 +44,7 @@ static void draw_example(SkSurface* surface, const SkPaint& paint, double rotati
@interface AppViewDelegate : NSObject <MTKViewDelegate>
@property (assign, nonatomic) GrContext* grContext; // non-owning pointer.
@property (assign, nonatomic) id<MTLCommandQueue> metalQueue;
@end
@implementation AppViewDelegate {
@ -70,7 +71,10 @@ static void draw_example(SkSurface* surface, const SkPaint& paint, double rotati
// Must flush *and* present for this to work!
surface->flush();
surface = nullptr;
[[view currentDrawable] present];
id<MTLCommandBuffer> commandBuffer = [[self metalQueue] commandBuffer];
[commandBuffer presentDrawable:[view currentDrawable]];
[commandBuffer commit];
}
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
@ -82,6 +86,7 @@ static void draw_example(SkSurface* surface, const SkPaint& paint, double rotati
@interface AppViewController : UIViewController
@property (strong, nonatomic) id<MTLDevice> metalDevice;
@property (strong, nonatomic) id<MTLCommandQueue> metalQueue;
@end
@implementation AppViewController {
@ -96,8 +101,9 @@ static void draw_example(SkSurface* surface, const SkPaint& paint, double rotati
[super viewDidLoad];
if (!fGrContext) {
[self setMetalDevice:MTLCreateSystemDefaultDevice()];
[self setMetalQueue:[[self metalDevice] newCommandQueue]];
GrContextOptions grContextOptions; // set different options here.
fGrContext = SkMetalDeviceToGrContext([self metalDevice], grContextOptions);
fGrContext = SkMetalDeviceToGrContext([self metalDevice], [self metalQueue], grContextOptions);
}
if (![self view] || ![self metalDevice]) {
NSLog(@"Metal is not supported on this device");
@ -110,6 +116,7 @@ static void draw_example(SkSurface* surface, const SkPaint& paint, double rotati
SkMtkViewConfigForSkia(mtkView);
AppViewDelegate* viewDelegate = [[AppViewDelegate alloc] init];
[viewDelegate setGrContext:fGrContext.get()];
[viewDelegate setMetalQueue:[self metalQueue]];
[viewDelegate mtkView:mtkView drawableSizeWillChange:[mtkView bounds].size];
[mtkView setDelegate:viewDelegate];
}

View File

@ -12,7 +12,7 @@ template <typename T> class sk_sp;
sk_sp<SkSurface> SkMtkViewToSurface(MTKView*, GrContext*);
sk_sp<GrContext> SkMetalDeviceToGrContext(id<MTLDevice>, const GrContextOptions&);
sk_sp<GrContext> SkMetalDeviceToGrContext(id<MTLDevice>, id<MTLCommandQueue>, const GrContextOptions&);
void SkMtkViewConfigForSkia(MTKView*);

View File

@ -41,9 +41,8 @@ sk_sp<SkSurface> SkMtkViewToSurface(MTKView* mtkView, GrContext* grContext) {
}
}
sk_sp<GrContext> SkMetalDeviceToGrContext(id<MTLDevice> device, const GrContextOptions& opts) {
return GrContext::MakeMetal((void*)device,
(void*)[device newCommandQueue], opts);
sk_sp<GrContext> SkMetalDeviceToGrContext(id<MTLDevice> device, id<MTLCommandQueue> queue, const GrContextOptions& opts) {
return GrContext::MakeMetal((void*)device, (void*)queue, opts);
}
void SkMtkViewConfigForSkia(MTKView* mtkView) {

View File

@ -14,6 +14,9 @@ class GrContext;
// e.g.: use SkMetalDeviceToGrContext().
@property (assign) GrContext* grContext; // non-owning pointer.
// Must be set to a valid MTLCommandQueue. Will be used to present.
@property (assign) id<MTLCommandQueue> queue; // non-owning pointer.
// When set, pauses at end of loop.
@property (assign) BOOL stopAtEnd;

View File

@ -63,7 +63,10 @@
fAnimation->render(canvas);
surface->flush();
surface = nullptr;
[[self currentDrawable] present];
id<MTLCommandBuffer> commandBuffer = [[self queue] commandBuffer];
[commandBuffer presentDrawable:[self currentDrawable]];
[commandBuffer commit];
}
- (BOOL)loadAnimation:(NSData*) data {

View File

@ -13,6 +13,7 @@
static UIStackView* make_skottie_stack(CGFloat width,
id<MTLDevice> metalDevice,
id<MTLCommandQueue> metalQueue,
GrContext* grContext) {
UIStackView* stack = [[UIStackView alloc] init];
[stack setAxis:UILayoutConstraintAxisVertical];
@ -35,6 +36,7 @@ static UIStackView* make_skottie_stack(CGFloat width,
continue;
}
[skottieView setDevice:metalDevice];
[skottieView setQueue:metalQueue];
[skottieView setGrContext:grContext];
SkMtkViewConfigForSkia(skottieView);
CGSize animSize = [skottieView size];
@ -52,6 +54,7 @@ static UIStackView* make_skottie_stack(CGFloat width,
@interface AppViewController : UIViewController
@property (strong) id<MTLDevice> metalDevice;
@property (strong) id<MTLCommandQueue> metalQueue;
@property (strong) UIStackView* stackView;
@end
@ -76,12 +79,14 @@ static UIStackView* make_skottie_stack(CGFloat width,
NSLog(@"Metal is not supported on this device");
return;
}
[self setMetalQueue:[[self metalDevice] newCommandQueue]];
GrContextOptions grContextOptions; // set different options here.
fGrContext = SkMetalDeviceToGrContext([self metalDevice], grContextOptions);
fGrContext = SkMetalDeviceToGrContext([self metalDevice], [self metalQueue],
grContextOptions);
}
[self setStackView:make_skottie_stack([[UIScreen mainScreen] bounds].size.width,
[self metalDevice], fGrContext.get())];
[self metalDevice], [self metalQueue], fGrContext.get())];
CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
CGSize mainScreenSize = [[UIScreen mainScreen] bounds].size;