From b4675905d278ece91ed7d3453480ddc87fa310ea Mon Sep 17 00:00:00 2001 From: Daniel Collin Date: Tue, 1 Oct 2019 16:36:33 +0200 Subject: [PATCH] WIP on macOS resizing support --- src/native/macosx/MacMiniFB.m | 29 +++++++++----- src/native/macosx/OSXWindow.h | 1 + src/native/macosx/OSXWindow.m | 7 ++++ src/native/macosx/OSXWindowFrameView.h | 7 +++- src/native/macosx/OSXWindowFrameView.m | 53 ++++++++++++++++++++++---- 5 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/native/macosx/MacMiniFB.m b/src/native/macosx/MacMiniFB.m index a627b57..8c601dd 100644 --- a/src/native/macosx/MacMiniFB.m +++ b/src/native/macosx/MacMiniFB.m @@ -8,12 +8,12 @@ extern id g_metal_device; extern id g_command_queue; extern id g_library; -extern id g_pipeline_state; +extern id g_pipeline_state; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// NSString* g_shadersSrc = @ -" #include \n" +" #include \n" "using namespace metal;\n" "struct VertexOutput {\n" @@ -108,9 +108,9 @@ static bool create_shaders() { // Error update if (nsError || !library) { - NSLog(@"Unable to create shaders %@", nsError); + NSLog(@"Unable to create shaders %@", nsError); return false; - } + } NSLog(@"Names %@", [g_library functionNames]); @@ -173,7 +173,7 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal s_init = true; } - NSWindowStyleMask styles = NSWindowStyleMaskClosable | NSWindowStyleMaskResizable; + NSWindowStyleMask styles = NSWindowStyleMaskClosable | NSWindowStyleMaskResizable; if (flags & WINDOW_BORDERLESS) styles |= NSWindowStyleMaskBorderless; @@ -191,7 +191,7 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal if (!window) return 0; - window->draw_buffer = malloc(width * height * 4); + window->draw_buffer = malloc((width * height * 4) * 8); if (!window->draw_buffer) return 0; @@ -199,7 +199,6 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal // Setup command queue g_command_queue = [g_metal_device newCommandQueue]; - WindowViewController* viewController = [WindowViewController new]; MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init]; @@ -213,7 +212,7 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal textureDescriptor.height = height; // Create the texture from the device by using the descriptor - + for (int i = 0; i < MaxBuffersInFlight; ++i) { viewController->m_texture_buffers[i] = [g_metal_device newTextureWithDescriptor:textureDescriptor]; } @@ -223,13 +222,17 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal viewController->m_draw_buffer = window->draw_buffer; viewController->m_width = width; viewController->m_height = height; + viewController->m_delayed_delete_count = 0; MTKView* view = [[MTKView alloc] initWithFrame:rectangle]; - view.device = g_metal_device; + view.device = g_metal_device; view.delegate = viewController; view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; [window.contentView addSubview:view]; + OSXWindowFrameView* temp_view = window->frame_view; + temp_view->m_view_controller = viewController; + window->width = width; window->height = height; window->scale = scale; @@ -451,7 +454,13 @@ int mfb_update(void* window, void* buffer) int mfb_update_with_buffer(void* window, void* buffer) { OSXWindow* win = (OSXWindow*)window; - memcpy(win->draw_buffer, buffer, win->width * win->height * 4); + + if (win->shared_data) { + SharedData* shared_data = (SharedData*)win->shared_data; + memcpy(win->draw_buffer, buffer, shared_data->width * shared_data->height * 4); + } else { + memcpy(win->draw_buffer, buffer, win->width * win->height * 4); + } int state = generic_update(win); diff --git a/src/native/macosx/OSXWindow.h b/src/native/macosx/OSXWindow.h index fb7e144..9bbc9ae 100644 --- a/src/native/macosx/OSXWindow.h +++ b/src/native/macosx/OSXWindow.h @@ -53,6 +53,7 @@ void build_submenu(NSMenu* menu, MenuDesc* desc); @public int active_menu_id; @public int prev_cursor; @public MenuData* menu_data; + @public void* frame_view; } diff --git a/src/native/macosx/OSXWindow.m b/src/native/macosx/OSXWindow.m index 0f5d450..22e76c1 100644 --- a/src/native/macosx/OSXWindow.m +++ b/src/native/macosx/OSXWindow.m @@ -144,12 +144,19 @@ object:self]; frameView = [[[OSXWindowFrameView alloc] initWithFrame:bounds] autorelease]; + [super setContentView:frameView]; } + frame_view = frameView; + if (childContentView) [childContentView removeFromSuperview]; + printf("osxwindow: setContentFrameView %p\n", frameView); + //printf("osxwindow: setting controller %p\n", view_controller); + //frameView->m_view_controller = view_controller; + //NSRect t = [self contentRectForFrameRect:bounds]; childContentView = aView; diff --git a/src/native/macosx/OSXWindowFrameView.h b/src/native/macosx/OSXWindowFrameView.h index 96062c4..01458ea 100644 --- a/src/native/macosx/OSXWindowFrameView.h +++ b/src/native/macosx/OSXWindowFrameView.h @@ -6,13 +6,15 @@ const int MaxBuffersInFlight = 3; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -@interface WindowViewController : NSViewController +@interface WindowViewController : NSViewController { - @public id m_texture_buffers[MaxBuffersInFlight]; + @public id m_texture_buffers[MaxBuffersInFlight]; + @public id m_delayed_delete_textures[MaxBuffersInFlight]; @public int m_current_buffer; @public void* m_draw_buffer; @public int m_width; @public int m_height; + @public int m_delayed_delete_count; // Used for syncing with CPU/GPU @public dispatch_semaphore_t m_semaphore; } @@ -23,6 +25,7 @@ const int MaxBuffersInFlight = 3; @interface OSXWindowFrameView : NSView { + @public WindowViewController* m_view_controller; //@public int scale; //@public int width; //@public int height; diff --git a/src/native/macosx/OSXWindowFrameView.m b/src/native/macosx/OSXWindowFrameView.m index 637557f..bca64c6 100644 --- a/src/native/macosx/OSXWindowFrameView.m +++ b/src/native/macosx/OSXWindowFrameView.m @@ -178,6 +178,51 @@ id g_pipeline_state; object:[self window]]; } +- (void)viewDidEndLiveResize +{ + //NSRect originalFrame = [win frame]; + //NSRect contentRect = [NSWindow contentRectForFrameRect: originalFrame styleMask: NSWindowStyleMaskTitled]; + NSSize size = [self bounds].size; + //NSSize size = [[self contentView] frame].size; + OSXWindow* window = (OSXWindow*)[self window]; + + int width = (int)size.width; + int height = (int)size.height; + + // if windows is resized we need to create new textures so we do that here and put the old textures in a + // "to delete" queue and set a frame counter of 3 frames before the gets released + + if (window->shared_data) { + if ((width != window->shared_data->width) || + (height != window->shared_data->height)) { + + MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init]; + + // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is + // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0) + textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm; + + // Set the pixel dimensions of the texture + textureDescriptor.width = width; + textureDescriptor.height = height; + + // Create the texture from the device by using the descriptor + + m_view_controller->m_width = width; + m_view_controller->m_height = height; + + for (int i = 0; i < MaxBuffersInFlight; ++i) { + m_view_controller->m_delayed_delete_count = 3; + m_view_controller->m_delayed_delete_textures[i] = m_view_controller->m_texture_buffers[i]; + m_view_controller->m_texture_buffers[i] = [g_metal_device newTextureWithDescriptor:textureDescriptor]; + } + } + + window->shared_data->width = width; + window->shared_data->height = height; + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc @@ -190,14 +235,6 @@ id g_pipeline_state; - (void)windowResized:(NSNotification *)notification { - (void)notification; - NSSize size = [self bounds].size; - OSXWindow* window = (OSXWindow*)[self window]; - - if (window->shared_data) { - window->shared_data->width = (int)(size.width); - window->shared_data->height = (int)(size.height); - } } @end