mirror of https://github.com/encounter/SDL.git
Leave the Metal view active on the window when recreating the Metal renderer
Fixes https://github.com/libsdl-org/SDL/issues/5140 Also move the metal tag definition to SDL_syswm.h so it can be used by applications
This commit is contained in:
parent
88ac517df0
commit
4b38d4c96b
|
@ -98,6 +98,10 @@ typedef struct _UIViewController UIViewController;
|
||||||
typedef Uint32 GLuint;
|
typedef Uint32 GLuint;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)
|
||||||
|
#define SDL_METALVIEW_TAG 255
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SDL_VIDEO_DRIVER_ANDROID)
|
#if defined(SDL_VIDEO_DRIVER_ANDROID)
|
||||||
typedef struct ANativeWindow ANativeWindow;
|
typedef struct ANativeWindow ANativeWindow;
|
||||||
typedef void *EGLSurface;
|
typedef void *EGLSurface;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
#ifdef __MACOSX__
|
#ifdef __MACOSX__
|
||||||
|
#import <AppKit/NSWindow.h>
|
||||||
#import <AppKit/NSView.h>
|
#import <AppKit/NSView.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1565,7 +1566,11 @@ METAL_DestroyRenderer(SDL_Renderer * renderer)
|
||||||
|
|
||||||
DestroyAllPipelines(data.allpipelines, data.pipelinescount);
|
DestroyAllPipelines(data.allpipelines, data.pipelinescount);
|
||||||
|
|
||||||
SDL_Metal_DestroyView(data.mtlview);
|
/* Release the metal view instead of destroying it,
|
||||||
|
in case we want to use it later (recreating the renderer)
|
||||||
|
*/
|
||||||
|
/* SDL_Metal_DestroyView(data.mtlview); */
|
||||||
|
CFBridgingRelease(data.mtlview);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(renderer);
|
SDL_free(renderer);
|
||||||
|
@ -1608,6 +1613,33 @@ METAL_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||||
return SDL_SetError("This Apple OS does not support displaySyncEnabled!");
|
return SDL_SetError("This Apple OS does not support displaySyncEnabled!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_MetalView GetWindowView(SDL_Window *window)
|
||||||
|
{
|
||||||
|
SDL_SysWMinfo info;
|
||||||
|
|
||||||
|
SDL_VERSION(&info.version);
|
||||||
|
if (SDL_GetWindowWMInfo(window, &info)) {
|
||||||
|
#ifdef __MACOSX__
|
||||||
|
if (info.subsystem == SDL_SYSWM_COCOA) {
|
||||||
|
NSView *view = info.info.cocoa.window.contentView;
|
||||||
|
if (view.subviews.count > 0) {
|
||||||
|
view = view.subviews[0];
|
||||||
|
if (view.tag == SDL_METALVIEW_TAG) {
|
||||||
|
return (SDL_MetalView)CFBridgingRetain(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (info.subsystem == SDL_SYSWM_UIKIT) {
|
||||||
|
UIView *view = info.info.uikit.window.rootViewController.view;
|
||||||
|
if (view.tag == SDL_METALVIEW_TAG) {
|
||||||
|
return (SDL_MetalView)CFBridgingRetain(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_Renderer *
|
static SDL_Renderer *
|
||||||
METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
|
@ -1659,7 +1691,10 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
view = SDL_Metal_CreateView(window);
|
view = GetWindowView(window);
|
||||||
|
if (view == nil) {
|
||||||
|
view = SDL_Metal_CreateView(window);
|
||||||
|
}
|
||||||
|
|
||||||
if (view == NULL) {
|
if (view == NULL) {
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
|
@ -1679,7 +1714,11 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
[mtldevice release];
|
[mtldevice release];
|
||||||
#endif
|
#endif
|
||||||
SDL_Metal_DestroyView(view);
|
/* Release the metal view instead of destroying it,
|
||||||
|
in case we want to use it later (recreating the renderer)
|
||||||
|
*/
|
||||||
|
/* SDL_Metal_DestroyView(view); */
|
||||||
|
CFBridgingRelease(view);
|
||||||
SDL_free(renderer);
|
SDL_free(renderer);
|
||||||
if (changed_window) {
|
if (changed_window) {
|
||||||
SDL_RecreateWindow(window, window_flags);
|
SDL_RecreateWindow(window, window_flags);
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
#define METALVIEW_TAG 255
|
|
||||||
|
|
||||||
@interface SDL_cocoametalview : NSView
|
@interface SDL_cocoametalview : NSView
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
|
#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
|
||||||
|
|
||||||
#include "SDL_events.h"
|
#include "SDL_events.h"
|
||||||
|
#include "SDL_syswm.h"
|
||||||
|
|
||||||
|
|
||||||
static int SDLCALL
|
static int SDLCALL
|
||||||
SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
|
SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
|
||||||
|
@ -103,7 +105,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
|
||||||
|
|
||||||
- (NSInteger)tag
|
- (NSInteger)tag
|
||||||
{
|
{
|
||||||
return METALVIEW_TAG;
|
return SDL_METALVIEW_TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateDrawableSize
|
- (void)updateDrawableSize
|
||||||
|
@ -173,7 +175,7 @@ Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
|
||||||
{ @autoreleasepool {
|
{ @autoreleasepool {
|
||||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||||
NSView *contentView = data->sdlContentView;
|
NSView *contentView = data->sdlContentView;
|
||||||
SDL_cocoametalview* metalview = [contentView viewWithTag:METALVIEW_TAG];
|
SDL_cocoametalview* metalview = [contentView viewWithTag:SDL_METALVIEW_TAG];
|
||||||
if (metalview) {
|
if (metalview) {
|
||||||
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
|
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
|
||||||
SDL_assert(layer != NULL);
|
SDL_assert(layer != NULL);
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
#define METALVIEW_TAG 255
|
|
||||||
|
|
||||||
@interface SDL_uikitmetalview : SDL_uikitview
|
@interface SDL_uikitmetalview : SDL_uikitview
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,9 @@
|
||||||
|
|
||||||
#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
|
#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
|
||||||
|
|
||||||
#import "../SDL_sysvideo.h"
|
#include "SDL_syswm.h"
|
||||||
|
#include "../SDL_sysvideo.h"
|
||||||
|
|
||||||
#import "SDL_uikitwindow.h"
|
#import "SDL_uikitwindow.h"
|
||||||
#import "SDL_uikitmetalview.h"
|
#import "SDL_uikitmetalview.h"
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@
|
||||||
scale:(CGFloat)scale
|
scale:(CGFloat)scale
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
self.tag = METALVIEW_TAG;
|
self.tag = SDL_METALVIEW_TAG;
|
||||||
self.layer.contentsScale = scale;
|
self.layer.contentsScale = scale;
|
||||||
[self updateDrawableSize];
|
[self updateDrawableSize];
|
||||||
}
|
}
|
||||||
|
@ -122,7 +124,7 @@ UIKit_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||||
SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
|
SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
|
||||||
SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG];
|
SDL_uikitmetalview* metalview = [view viewWithTag:SDL_METALVIEW_TAG];
|
||||||
if (metalview) {
|
if (metalview) {
|
||||||
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
|
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
|
||||||
assert(layer != NULL);
|
assert(layer != NULL);
|
||||||
|
|
Loading…
Reference in New Issue