blob: b274ed4d606ecc22e8299fc695dbc7c99d24507d [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#include "flutter/shell/platform/embedder/embedder.h"
#pragma mark - Static callbacks that require the engine.
static FlutterMetalTexture OnGetNextDrawable(FlutterEngine* engine,
const FlutterFrameInfo* frameInfo) {
CGSize size = CGSizeMake(frameInfo->size.width, frameInfo->size.height);
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(engine.renderer);
return [metalRenderer createTextureForSize:size];
}
static bool OnPresentDrawable(FlutterEngine* engine, const FlutterMetalTexture* texture) {
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(engine.renderer);
return [metalRenderer present:texture->texture_id];
}
static bool OnAcquireExternalTexture(FlutterEngine* engine,
int64_t textureIdentifier,
size_t width,
size_t height,
FlutterMetalExternalTexture* metalTexture) {
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(engine.renderer);
return [metalRenderer populateTextureWithIdentifier:textureIdentifier metalTexture:metalTexture];
}
#pragma mark - FlutterMetalRenderer implementation
@implementation FlutterMetalRenderer {
__weak FlutterEngine* _engine;
FlutterView* _flutterView;
FlutterDarwinContextMetal* _darwinMetalContext;
}
- (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine {
self = [super initWithDelegate:self engine:flutterEngine];
if (self) {
_engine = flutterEngine;
_device = MTLCreateSystemDefaultDevice();
if (!_device) {
NSLog(@"Could not acquire Metal device.");
return nil;
}
_commandQueue = [_device newCommandQueue];
if (!_commandQueue) {
NSLog(@"Could not create Metal command queue.");
return nil;
}
_darwinMetalContext = [[FlutterDarwinContextMetal alloc] initWithMTLDevice:_device
commandQueue:_commandQueue];
}
return self;
}
- (void)setFlutterView:(FlutterView*)view {
_flutterView = view;
}
- (FlutterRendererConfig)createRendererConfig {
FlutterRendererConfig config = {
.type = FlutterRendererType::kMetal,
.metal.struct_size = sizeof(FlutterMetalRendererConfig),
.metal.device = (__bridge FlutterMetalDeviceHandle)_device,
.metal.present_command_queue = (__bridge FlutterMetalCommandQueueHandle)_commandQueue,
.metal.get_next_drawable_callback =
reinterpret_cast<FlutterMetalTextureCallback>(OnGetNextDrawable),
.metal.present_drawable_callback =
reinterpret_cast<FlutterMetalPresentCallback>(OnPresentDrawable),
.metal.external_texture_frame_callback =
reinterpret_cast<FlutterMetalTextureFrameCallback>(OnAcquireExternalTexture),
};
return config;
}
#pragma mark - Embedder callback implementations.
- (FlutterMetalTexture)createTextureForSize:(CGSize)size {
FlutterMetalRenderBackingStore* backingStore =
(FlutterMetalRenderBackingStore*)[_flutterView backingStoreForSize:size];
id<MTLTexture> texture = backingStore.texture;
FlutterMetalTexture embedderTexture;
embedderTexture.struct_size = sizeof(FlutterMetalTexture);
embedderTexture.texture = (__bridge void*)texture;
embedderTexture.texture_id = reinterpret_cast<int64_t>(texture);
return embedderTexture;
}
- (BOOL)present:(int64_t)textureID {
if (!_flutterView) {
return NO;
}
[_flutterView present];
return YES;
}
#pragma mark - FlutterTextureRegistrar methods.
- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
metalTexture:(FlutterMetalExternalTexture*)textureOut {
id<FlutterMacOSExternalTexture> texture = [self getTextureWithID:textureID];
FlutterExternalTextureMetal* metalTexture =
reinterpret_cast<FlutterExternalTextureMetal*>(texture);
return [metalTexture populateTexture:textureOut];
}
- (id<FlutterMacOSExternalTexture>)onRegisterTexture:(id<FlutterTexture>)texture {
return [[FlutterExternalTextureMetal alloc] initWithFlutterTexture:texture
darwinMetalContext:_darwinMetalContext];
}
@end