Skip to content

Commit

Permalink
IGL: Update Mac session to use IRenderSessionFactory to configure ses…
Browse files Browse the repository at this point in the history
…sion

Summary: This diff updates the mac shell to use IRenderSessionFactory to configure the session and window.

Reviewed By: syeh1

Differential Revision: D63036078

fbshipit-source-id: a0da1823c5cb03cff08ae4c6c1c19155de73f87f
  • Loading branch information
Eric Griffith authored and facebook-github-bot committed Sep 20, 2024
1 parent e6afc75 commit d38c867
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 70 deletions.
170 changes: 119 additions & 51 deletions shell/mac/AppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#import "ViewController.h"

#import <igl/Common.h>
#include <shell/shared/renderSession/DefaultRenderSessionFactory.h>
#include <shell/shared/renderSession/RenderSessionConfig.h>
#include <shell/shared/renderSession/transition/TransitionRenderSessionFactory.h>

namespace {

Expand Down Expand Up @@ -63,7 +66,11 @@ @interface AppDelegate ()

@property (weak) IBOutlet NSWindow* window;
@property NSTabViewController* tabViewController;
@property std::shared_ptr<igl::shell::IRenderSessionFactory> factory;

- (void)addTab:(igl::shell::RenderSessionWindowConfig)windowConfig
sessionConfig:(igl::shell::RenderSessionConfig)sessionConfig
frame:(CGRect)frame;
@end

@implementation AppDelegate
Expand All @@ -76,75 +83,136 @@ - (void)applicationDidFinishLaunching:(NSNotification*)aNotification {

- (void)setupViewController {
self.tabViewController = [[NSTabViewController alloc] init];
auto frame = [self.window frame];
(void)frame;
ViewController* viewController = nullptr;

self.factory = igl::shell::createDefaultRenderSessionFactory();

igl::shell::RenderSessionWindowConfig suggestedWindowConfig = {
.width = 1024,
.height = 768,
.windowMode = igl::shell::WindowMode::Window,
};
std::vector<igl::shell::RenderSessionConfig> suggestedSessionConfigs = {
#if IGL_BACKEND_HEADLESS
// Headless tab
NSTabViewItem* tinyHeadlessTabViewItem = [[NSTabViewItem alloc] initWithIdentifier:nil];
viewController = [[ViewController alloc] initWithFrame:frame
backendVersion:{igl::BackendFlavor::Invalid, 0, 0}];

tinyHeadlessTabViewItem.viewController = viewController;
tinyHeadlessTabViewItem.label = @"Headless";
[self.tabViewController addTabViewItem:tinyHeadlessTabViewItem];
{
.displayName = "Headless",
.backendVersion = {.flavor = igl::BackendFlavor::Invalid,
.majorVersion = 0,
.minorVersion = 0},
.colorFramebufferFormat = igl::TextureFormat::RGBA_SRGB,
},
#endif

#if IGL_BACKEND_METAL
// Metal tab
NSTabViewItem* tinyMetalTabViewItem = [[NSTabViewItem alloc] initWithIdentifier:nil];
viewController = [[ViewController alloc] initWithFrame:frame
backendVersion:{igl::BackendFlavor::Metal, 3, 0}];
tinyMetalTabViewItem.viewController = viewController;

tinyMetalTabViewItem.label = @"Metal";
[self.tabViewController addTabViewItem:tinyMetalTabViewItem];
{
.displayName = "Metal",
.backendVersion = {.flavor = igl::BackendFlavor::Metal,
.majorVersion = 3,
.minorVersion = 0},
.colorFramebufferFormat = igl::TextureFormat::BGRA_SRGB,
},
#endif

#if IGL_BACKEND_OPENGL
// OpenGL tab
NSTabViewItem* tinyOGL4TabViewItem = [[NSTabViewItem alloc] initWithIdentifier:nil];
viewController = [[ViewController alloc] initWithFrame:frame
backendVersion:{igl::BackendFlavor::OpenGL, 4, 1}];
tinyOGL4TabViewItem.viewController = viewController;

tinyOGL4TabViewItem.label = @"OGL 4.1";
[self.tabViewController addTabViewItem:tinyOGL4TabViewItem];
// @fb-only
// @fb-only
// @fb-only
{
.displayName = "OGL 4.1",
.backendVersion = {.flavor = igl::BackendFlavor::OpenGL,
.majorVersion = 4,
.minorVersion = 1},
.colorFramebufferFormat = igl::TextureFormat::BGRA_SRGB,
},
// clang-format off
// @fb-only
// clang-format on
// @fb-only
// @fb-only
// @fb-only
// @fb-only
// @fb-only

NSColorSpace* metalColorSpace = colorSpaceToNSColorSpace(viewController.colorSpace);
[self.window setColorSpace:metalColorSpace];
// @fb-only
// @fb-only
// @fb-only
#endif

// @fb-only
// @fb-only
// @fb-only
// @fb-only
// clang-format off
// @fb-only
// clang-format on
// @fb-only
// @fb-only
// @fb-only
// @fb-only
// @fb-only
// @fb-only
// @fb-only
// @fb-only
#if IGL_BACKEND_VULKAN
{
.displayName = "Vulkan",
.backendVersion = {.flavor = igl::BackendFlavor::Vulkan,
.majorVersion = 1,
.minorVersion = 1},
.colorFramebufferFormat = igl::TextureFormat::BGRA_SRGB,
},
#endif
};

const auto requestedWindowConfig = self.factory->requestedWindowConfig(suggestedWindowConfig);

IGL_ASSERT(requestedWindowConfig.windowMode == igl::shell::WindowMode::Window ||
requestedWindowConfig.windowMode == igl::shell::WindowMode::MaximizedWindow);

CGRect frame = requestedWindowConfig.windowMode == igl::shell::WindowMode::Window
? [self.window frame]
: [[NSScreen mainScreen] frame];
if (requestedWindowConfig.windowMode == igl::shell::WindowMode::Window) {
frame.size = CGSizeMake(requestedWindowConfig.width, requestedWindowConfig.height);
}

const auto requestedSessionConfigs =
self.factory->requestedSessionConfigs(std::move(suggestedSessionConfigs));
for (const auto& sessionConfig : requestedSessionConfigs) {
[self addTab:requestedWindowConfig sessionConfig:sessionConfig frame:frame];
}
}

- (void)addTab:(igl::shell::RenderSessionWindowConfig)windowConfig
sessionConfig:(igl::shell::RenderSessionConfig)sessionConfig
frame:(CGRect)frame {
ViewController* viewController = nullptr;
bool supported = false;
#if IGL_BACKEND_HEADLESS
if (sessionConfig.backendVersion.flavor == igl::BackendFlavor::Invalid) {
supported = true;
}
#endif
#if IGL_BACKEND_METAL
if (sessionConfig.backendVersion.flavor == igl::BackendFlavor::Metal) {
supported = true;
}
#endif
#if IGL_BACKEND_OPENGL
if (sessionConfig.backendVersion.flavor == igl::BackendFlavor::OpenGL) {
supported = true;
NSColorSpace* metalColorSpace = colorSpaceToNSColorSpace(viewController.colorSpace);
[self.window setColorSpace:metalColorSpace];
}
#endif
// @fb-only
// @fb-only
// @fb-only
// @fb-only
// @fb-only

#if IGL_BACKEND_VULKAN
// Vulkan tab
NSTabViewItem* tinyVulkanTabViewItem = [[NSTabViewItem alloc] initWithIdentifier:nil];
if (sessionConfig.backendVersion.flavor == igl::BackendFlavor::Vulkan) {
supported = true;
}
#endif
if (!IGL_VERIFY(supported)) {
return;
}

NSTabViewItem* tabViewItem = [[NSTabViewItem alloc] initWithIdentifier:nil];

viewController = [[ViewController alloc] initWithFrame:frame
backendVersion:{igl::BackendFlavor::Vulkan, 1, 3}];
factory:*self.factory
config:sessionConfig];

tinyVulkanTabViewItem.viewController = viewController;
tinyVulkanTabViewItem.label = @"Vulkan";
[self.tabViewController addTabViewItem:tinyVulkanTabViewItem];
#endif
tabViewItem.viewController = viewController;
tabViewItem.label = [NSString stringWithUTF8String:sessionConfig.displayName.c_str()];
[self.tabViewController addTabViewItem:tabViewItem];

self.window.contentViewController = self.tabViewController;
[self.window setFrame:viewController.frame display:YES animate:false];
Expand Down
4 changes: 3 additions & 1 deletion shell/mac/ViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
#import <MetalKit/MetalKit.h>
#import <igl/Common.h>
#import <igl/DeviceFeatures.h>
#import <shell/shared/renderSession/IRenderSessionFactory.h>

NS_ASSUME_NONNULL_BEGIN
@interface ViewController : NSViewController <MTKViewDelegate>

@property (nonatomic) NSView* iglView;

- (instancetype)initWithFrame:(CGRect)frame
backendVersion:(igl::BackendVersion)backendType NS_DESIGNATED_INITIALIZER;
factory:(igl::shell::IRenderSessionFactory&)factory
config:(igl::shell::RenderSessionConfig)config;

// Explicitly disable superclass' designated initializers
- (instancetype)initWithNibName:(nullable NSNibName)nibNameOrNil
Expand Down
42 changes: 24 additions & 18 deletions shell/mac/ViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <shell/shared/platform/mac/PlatformMac.h>
#include <shell/shared/renderSession/AppParams.h>
#include <shell/shared/renderSession/DefaultSession.h>
#include <shell/shared/renderSession/RenderSession.h>
#include <shell/shared/renderSession/ShellParams.h>
// @fb-only
// @fb-only
Expand All @@ -48,7 +49,8 @@
using namespace igl;

@interface ViewController () {
igl::BackendVersion backendVersion_;
igl::shell::IRenderSessionFactory* factory_;
igl::shell::RenderSessionConfig config_;
igl::shell::ShellParams shellParams_;
CGRect frame_;
CVDisplayLinkRef displayLink_; // For OpenGL only
Expand All @@ -66,16 +68,19 @@ @implementation ViewController
/// MARK: - Init
///--------------------------------------

- (instancetype)initWithFrame:(CGRect)frame backendVersion:(igl::BackendVersion)backendVersion {
- (instancetype)initWithFrame:(CGRect)frame
factory:(igl::shell::IRenderSessionFactory&)factory
config:(igl::shell::RenderSessionConfig)config {
self = [super initWithNibName:nil bundle:nil];
if (!self) {
return self;
}

backendVersion_ = backendVersion;
config_ = std::move(config);
factory_ = &factory;
shellParams_ = igl::shell::ShellParams();
frame.size.width = shellParams_.viewportSize.x;
frame.size.height = shellParams_.viewportSize.y;
shellParams_.viewportSize.x = frame.size.width;
shellParams_.viewportSize.y = frame.size.height;
frame_ = frame;
kMouseSpeed_ = 0.05f;
currentDrawable_ = nil;
Expand Down Expand Up @@ -109,7 +114,7 @@ - (void)render {
shellPlatform_->getInputDispatcher().processEvents();

igl::SurfaceTextures surfaceTextures;
if (backendVersion_.flavor != igl::BackendFlavor::Invalid &&
if (config_.backendVersion.flavor != igl::BackendFlavor::Invalid &&
shellPlatform_->getDevicePtr() != nullptr) {
// @fb-only
// @fb-only
Expand Down Expand Up @@ -150,7 +155,7 @@ - (void)loadView {
// return something that works
HWDeviceQueryDesc queryDesc(HWDeviceType::Unknown);

switch (backendVersion_.flavor) {
switch (config_.backendVersion.flavor) {
case igl::BackendFlavor::Invalid: {
auto headlessView = [[HeadlessView alloc] initWithFrame:frame_];
self.view = headlessView;
Expand Down Expand Up @@ -178,7 +183,7 @@ - (void)loadView {
metalView.delegate = self;

metalView.colorPixelFormat =
metal::Texture::textureFormatToMTLPixelFormat(shellParams_.defaultColorFramebufferFormat);
metal::Texture::textureFormatToMTLPixelFormat(config_.colorFramebufferFormat);
metalView.colorspace = metal::colorSpaceToCGColorSpace(shellParams_.swapchainColorSpace);

metalView.framebufferOnly = NO;
Expand All @@ -192,7 +197,7 @@ - (void)loadView {
#if IGL_BACKEND_OPENGL
case igl::BackendFlavor::OpenGL: {
NSOpenGLPixelFormat* pixelFormat;
if (backendVersion_.majorVersion == 4 && backendVersion_.minorVersion == 1) {
if (config_.backendVersion.majorVersion == 4 && config_.backendVersion.minorVersion == 1) {
static NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAllowOfflineRenderers,
Expand All @@ -212,7 +217,8 @@ - (void)loadView {
};
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
IGL_ASSERT_MSG(pixelFormat, "Requested attributes not supported");
} else if (backendVersion_.majorVersion == 3 && backendVersion_.minorVersion == 2) {
} else if (config_.backendVersion.majorVersion == 3 &&
config_.backendVersion.minorVersion == 2) {
static NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAllowOfflineRenderers,
Expand All @@ -231,7 +237,8 @@ - (void)loadView {
0,
};
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
} else if (backendVersion_.majorVersion == 2 && backendVersion_.minorVersion == 1) {
} else if (config_.backendVersion.majorVersion == 2 &&
config_.backendVersion.minorVersion == 1) {
static NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAllowOfflineRenderers,
Expand All @@ -253,8 +260,8 @@ - (void)loadView {
} else {
IGL_ASSERT_MSG(false,
"Unsupported OpenGL version: %u.%u\n",
backendVersion_.majorVersion,
backendVersion_.minorVersion);
config_.backendVersion.majorVersion,
config_.backendVersion.minorVersion);
}
auto openGLView = [[GLView alloc] initWithFrame:frame_ pixelFormat:pixelFormat];
igl::Result result;
Expand Down Expand Up @@ -282,8 +289,7 @@ - (void)loadView {
vulkanContextConfig.enableBufferDeviceAddress = true;

vulkanContextConfig.swapChainColorSpace = shellParams_.swapchainColorSpace;
vulkanContextConfig.requestedSwapChainTextureFormat =
shellParams_.defaultColorFramebufferFormat;
vulkanContextConfig.requestedSwapChainTextureFormat = config_.colorFramebufferFormat;

auto context =
igl::vulkan::HWDevice::createContext(vulkanContextConfig, (__bridge void*)vulkanView);
Expand Down Expand Up @@ -330,7 +336,7 @@ - (void)loadView {
}
}

session_ = igl::shell::createDefaultRenderSession(shellPlatform_);
session_ = factory_->createRenderSession(shellPlatform_);
IGL_ASSERT_MSG(session_, "createDefaultRenderSession() must return a valid session");
// Get initial native surface dimensions
shellParams_.nativeSurfaceDimensions = glm::ivec2(2048, 1536);
Expand Down Expand Up @@ -374,7 +380,7 @@ - (void)mtkView:(nonnull MTKView*)view drawableSizeDidChange:(CGSize)size {
}

- (std::shared_ptr<igl::ITexture>)createTextureFromNativeDrawable {
switch (backendVersion_.flavor) {
switch (config_.backendVersion.flavor) {
#if IGL_BACKEND_METAL
case igl::BackendFlavor::Metal: {
auto& device = shellPlatform_->getDevice();
Expand Down Expand Up @@ -424,7 +430,7 @@ - (void)mtkView:(nonnull MTKView*)view drawableSizeDidChange:(CGSize)size {
}

- (std::shared_ptr<igl::ITexture>)createTextureFromNativeDepth {
switch (backendVersion_.flavor) {
switch (config_.backendVersion.flavor) {
#if IGL_BACKEND_METAL
case igl::BackendFlavor::Metal: {
auto& device = shellPlatform_->getDevice();
Expand Down

0 comments on commit d38c867

Please sign in to comment.