在 OS X 上的全屏模式下,Sprite Kit 出现严重的 FPS 问题 [英] Sprite Kit Serious FPS Issue In Full Screen Mode on OS X

查看:19
本文介绍了在 OS X 上的全屏模式下,Sprite Kit 出现严重的 FPS 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个相当复杂的精灵套件游戏.我最近添加了对 OS X 的支持.我总是得到 60 fps,无论我的游戏在调整窗口大小时如何缩放(即使调整到最大屏幕空间).但是,当我让我的应用程序进入全屏"时,fps 会下降到 30-40 fps 并保持这种状态?但是,如果我在启用全屏时使用鼠标光标并显示菜单栏,则 fps 会回到 60 fps!

I'm making a fairly complex sprite kit game. I recently added support for OS X. I get 60 fps always, regardless of how my game is scaled when the window is resized (even when resized to max screen space). However, the moment I make my App enter "Full Screen," the fps drops to 30-40 fps and stays that way? But if I take my mouse cursor and reveal the menu bar while full screen is enabled, the fps goes back up to 60 fps!

您甚至可以通过使用默认模板在 Xcode 中为 mac 制作 sprite kit 游戏来测试此错误.这是我为 mac 的默认游戏模板拍摄的屏幕截图.

You can even test this bug by making a sprite kit game for mac in Xcode using the default template. Here are the screen shots I took of the default game template for mac.

我建议您自己尝试一下,如果您使用 Apple 为 OS X 提供的默认 sprite kit 模板,您甚至不必编写任何代码.

I suggest trying it out for yourself, you don't even have to write any code if you use Apple's default sprite kit template for OS X.

最大窗口(无 FPS 问题:59-60 FPS)

全屏模式(FPS 降至 30-40 FPS)

鼠标在顶部显示菜单栏的全屏模式(令人惊讶的是,没有 FPS 问题:59-60 FPS)

任何人都知道可能导致此问题的原因.如果这意味着用户将失去性能,我不想以全屏模式发布我的应用程序.您会认为全屏模式可以更好地优化绘图,但显然情况恰恰相反.我在 Yosemite 上运行它.

Anyone have any idea what might be causing this problem. I don't want to release my App with full screen mode if it means users will lose performance. You would think full screen mode could better optimize drawing but apparently it's quite the opposite. I'm running this on Yosemite.

推荐答案

好的,经过几周的研究,我找到了一些解决这个问题的方法.在开始之前,让我先解释一下我的设置.我在包含 SKView 的情节提要中使用 NSViewController.我已经在 MacBook Pro(Retina,15 英寸,2013 年初)上测试了解决方法,我不知道我下面介绍的解决方法是否适用于其他 Mac.我相信它应该,当我有机会时,我会测试并看看下面的解决方法是否有效.

Ok, after weeks looking into this issue I have found some workarounds to this issue. Before I begin, let me start by explaining my setup. I'm using an NSViewController in a storyboard which holds an SKView. I've tested the workaround on MacBook Pro (Retina, 15-inch, Early 2013), I have no idea if the workarounds I present below will work on other Macs. I believe it should, when I get the chance I will test and see if the workarounds below work.

所以在我开始之前,让我们回顾一下问题所在.问题是通过单击全屏按钮使您的应用程序进入全屏会导致 FPS 大幅下降.以下是启用全屏按钮的方法:

So before I begin, lets recap what the issue is. The issue is that making your App enter fullscreen by clicking the fullscreen button causes a massive drop in FPS. Below is how you enable the fullscreen button:

self.view.window!.collectionBehavior = .FullScreenPrimary

然后我四处搜索,发现使用此代码进入全屏的另一种方式:

So then I searched around and found a different way of entering fullscreen using this code:

 self.view.enterFullScreenMode(NSScreen.mainScreen()!, withOptions: nil)

但我的 FPS 仍然大幅下降.请记住,在最大化窗口模式甚至全屏且菜单栏可见时,我没有 fps 问题!(见有问题的图片).

But I still had a massive drop in FPS. Keep in mind, I had no fps issues when in maximized window mode or even full screen with the menu bar visible! (see pictures in question).

然后我尝试了一种不太高级的方法来全屏显示.我找到了 Apple 这里的指南

So then I tried a less high-level approach to going full screen. I found a guide by Apple here

使用指南中的一些代码,我设法通过将窗口大小设置为显示大小并将窗口定位在所有 OS X UI 上方来进入全屏模式.代码如下:

Using some of the code from the guide, I managed to enter fullscreen by setting the window size to the size of the display, and positioning the window above all OS X UI. The code for this is as follows:

self.view.window!.styleMask = NSBorderlessWindowMask
self.view.window!.level = Int(CGWindowLevelForKey(Int32(kCGMainMenuWindowLevelKey))) + 1
self.view.window!.opaque = true
self.view.window!.hidesOnDeactivate = true
let size = NSScreen.mainScreen()!.frame.size
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height), display:true)

但是,遗憾的是,同样的问题...... FPS 就像以前一样下降了.

But, sadly, same problem... The FPS just dropped just like before.

然后我想如果我弄乱了窗口的大小/位置怎么办.所以我尝试向下移动窗口,以便只看到菜单栏,如下所示.这行得通.我不再有fps下降.但显然它不是真正的全屏,因为菜单栏是可见的

So then I thought what if I mess with the size/position of the window. So I tried moving the window down so that just the menu bar was visible as shown below. AND THIS WORKED. I no longer had a drop in fps. But obviously it's not truly fullscreen because the menu bar is visible

self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height-NSApplication.sharedApplication().mainMenu!.menuBarHeight), display:true)

事实上,事实证明,只需将窗口大小调整 1 点即可修复 fps 的下降.因此,当您的窗口大小与屏幕大小匹配时,该错误必须与苹果所做的优化(多么讽刺)有关.

In fact, as it turns out, just be adjusting the window size by 1 point fixes the drop in fps. Thus the bug must be related to an optimization (how ironic) apple does when your window size matches the screen size.

不相信我?这是链接中的引用.

Don't believe me? Here is a quote from the link.

OS X v10.6 及更高版本自动优化性能屏幕大小窗口

OS X v10.6 and later automatically optimize the performance of screen-sized windows

所以要解决这个问题,我们需要做的就是让我们的窗口大小高度增加 1 点,这将阻止 OS X 尝试优化我们的窗口.这将导致您的应用在顶部略微被截断,但 1 像素根本不应该被注意到.在最坏的情况下,您可以将节点位置调整 1 个点来解决此问题.

So to fix the issue all we need to do is make our window size height 1 point larger which will prevent OS X from trying to optimize our window. This will cause your App to get slightly cut off on the top but 1 pixel shouldn't be noticeable at all. And in the worst case you could adjust your nodes position by 1 point to account for this.

为方便起见,下面列出了两种解决方法.这两种解决方法都不会导致 FPS 下降.您的应用程序应该像在最大化窗口模式下一样运行.第一个解决方法将您的应用程序置于全屏状态并在顶部显示菜单栏.第二种解决方法使您的应用完全全屏,没有菜单栏.

For your convenience, listed below are the 2 workarounds. Both of these workarounds do not cause any drop in FPS. Your App should function just like it did in maximized window mode. The first workaround puts your App in fullscreen and displays the menu bar at the top. The second workaround puts your App in complete full screen with no menu bar.

self.view.window!.styleMask = NSBorderlessWindowMask
self.view.window!.level = Int(CGWindowLevelForKey(Int32(kCGMainMenuWindowLevelKey))) + 1
self.view.window!.opaque = true
self.view.window!.hidesOnDeactivate = true

let size = NSScreen.mainScreen()!.frame.size
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height-NSApplication.sharedApplication().mainMenu!.menuBarHeight), display:true)

解决方法 2:没有菜单栏的全屏

self.view.window!.styleMask = NSBorderlessWindowMask
self.view.window!.level = Int(CGWindowLevelForKey(Int32(kCGMainMenuWindowLevelKey))) + 1
self.view.window!.opaque = true
self.view.window!.hidesOnDeactivate = true
let size = NSScreen.mainScreen()!.frame.size
NSMenu.setMenuBarVisible(false)
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height+1), display:true)

<小时>

如果由于某种原因这些变通办法不起作用,请尝试在窗口的大小/位置上多做一些处理.此外,您可能需要更改窗口级别,具体取决于您是否有其他视图,例如您的应用程序不应重叠的对话.另外请记得向 Apple 提交错误报告.

这些解决方法使用 NSBorderlessWindowMask.当键窗口改变时,这些类型的窗口不接受键盘输入.因此,如果您的游戏使用键盘输入,您应该覆盖以下内容.请参阅此处

These workarounds use an NSBorderlessWindowMask. These type of windows do not accept keyboard input when the key window changes. So if your game uses keyboard input, you should override the following. See here

 class CustomWindow: NSWindow {
    override var canBecomeKeyWindow: Bool {
        get {
            return true
        }
    }
    override var canBecomeMainWindow: Bool {
        get {
            return true
        }
    }
}

<小时>

更新:一些坏消息

在 Mac Book Air 上测试了这个解决方法,除非减去大约 100 分(这显然非常明显),否则它不起作用.我不知道为什么.andyvn22 的解决方案也是如此.我还注意到,很少,也许每 60 次启动一次,所提供的解决方法根本无法在 Mac Book Air 上运行.修复的唯一方法是重新启动应用程序.也许 Max Book Air 是一个特例.也许缺少显卡与这个问题有关.希望苹果能解决这个问题.我现在在支持全屏和不支持全屏之间纠结.我真的希望用户能够进入全屏模式,但同时我不想冒险让用户失去一半的 FPS.

Tested this workaround on Mac Book Air, and it did not work unless about 100 points were subtracted (which obviously is extremely noticeable). I have no idea why. Same goes for andyvn22's solution. I also have noticed that very rarely, perhaps once every 60 launches the workarounds provided simply don't work on the Mac Book Air at all. And the only way to fix is to relaunch the App. Maybe the Max Book Air is a special case. Maybe lack of a graphics card has to do with the issue. Hopefully Apple gets the issue sorted out. I'm now torn between supporting fullscreen and not supporting fullscreen. I really want users to be able to enter fullscreen mode, but at the same time I don't want to risk users loosing half their FPS.

这篇关于在 OS X 上的全屏模式下,Sprite Kit 出现严重的 FPS 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆