Merge branch '12.0-development' into metal

This commit is contained in:
Alex Szpakowski
2020-12-22 22:37:17 -04:00
288 changed files with 15292 additions and 12550 deletions
+12
View File
@@ -26,6 +26,18 @@ namespace love
namespace window
{
static bool highDPIAllowed = false;
void setHighDPIAllowed(bool enable)
{
highDPIAllowed = enable;
}
bool isHighDPIAllowed()
{
return highDPIAllowed;
}
Window::~Window()
{
}
+5 -2
View File
@@ -43,6 +43,10 @@ class Graphics;
namespace window
{
// Applied when the window is first created.
void setHighDPIAllowed(bool enable);
bool isHighDPIAllowed();
// Forward-declared so it can be used in the class methods. We can't define the
// whole thing here because it uses the Window::Type enum.
struct WindowSettings;
@@ -66,7 +70,7 @@ public:
SETTING_BORDERLESS,
SETTING_CENTERED,
SETTING_DISPLAY,
SETTING_HIGHDPI,
SETTING_HIGHDPI, // Deprecated
SETTING_USE_DPISCALE,
SETTING_REFRESHRATE,
SETTING_X,
@@ -261,7 +265,6 @@ struct WindowSettings
bool borderless = false;
bool centered = true;
int display = 0;
bool highdpi = false;
bool usedpiscale = true;
double refreshrate = 0.0;
bool useposition = false;
+112 -96
View File
@@ -94,7 +94,7 @@ void Window::setGraphics(graphics::Graphics *graphics)
this->graphics.set(graphics);
}
void Window::setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth)
void Window::setGLFramebufferAttributes(bool sRGB)
{
// Set GL window / framebuffer attributes.
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
@@ -102,12 +102,18 @@ void Window::setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int d
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil ? 8 : 0);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depth);
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0);
// Always use 24/8 depth/stencil (make sure any Graphics implementations
// that have their own backbuffer match this, too).
// Changing this after initial window creation would need the context to be
// destroyed and recreated, which we really don't want.
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
// Backbuffer MSAA is handled by the love.graphics implementation.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0);
@@ -289,7 +295,7 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
return attribslist;
}
bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer, int msaa, bool stencil, int depth)
bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer)
{
bool needsglcontext = (windowflags & SDL_WINDOW_OPENGL) != 0;
#ifdef LOVE_GRAPHICS_METAL
@@ -369,10 +375,9 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
// Try each context profile in order.
for (ContextAttribs attribs : attribslist)
{
int curMSAA = msaa;
bool curSRGB = love::graphics::isGammaCorrect();
setGLFramebufferAttributes(curMSAA, curSRGB, stencil, depth);
setGLFramebufferAttributes(curSRGB);
setGLContextAttributes(attribs);
windowerror.clear();
@@ -380,33 +385,14 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
create(&attribs);
if (!window && curMSAA > 0)
{
// The MSAA setting could have caused the failure.
setGLFramebufferAttributes(0, curSRGB, stencil, depth);
if (create(&attribs))
curMSAA = 0;
}
if (!window && curSRGB)
{
// same with sRGB.
setGLFramebufferAttributes(curMSAA, false, stencil, depth);
// The sRGB setting could have caused the failure.
setGLFramebufferAttributes(false);
if (create(&attribs))
curSRGB = false;
}
if (!window && curMSAA > 0 && curSRGB)
{
// Or both!
setGLFramebufferAttributes(0, false, stencil, depth);
if (create(&attribs))
{
curMSAA = 0;
curSRGB = false;
}
}
if (window && glcontext)
{
// Store the successful context attributes so we can re-use them in
@@ -481,6 +467,9 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
auto renderer = graphics != nullptr ? graphics->getRenderer() : graphics::Graphics::RENDERER_NONE;
if (isOpen())
updateSettings(this->settings, false);
WindowSettings f;
if (settings)
@@ -500,54 +489,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
height = mode.h;
}
Uint32 sdlflags = 0;
if (renderer == graphics::Graphics::RENDERER_OPENGL)
sdlflags |= SDL_WINDOW_OPENGL;
#ifdef LOVE_GRAPHICS_METAL
if (renderer == graphics::Graphics::RENDERER_METAL)
sdlflags |= SDL_WINDOW_METAL;
#endif
// On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP
#ifdef LOVE_ANDROID
f.fstype = FULLSCREEN_DESKTOP;
#endif
if (f.fullscreen)
{
if (f.fstype == FULLSCREEN_DESKTOP)
sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
else
{
sdlflags |= SDL_WINDOW_FULLSCREEN;
SDL_DisplayMode mode = {0, width, height, 0, nullptr};
// Fullscreen window creation will bug out if no mode can be used.
if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr)
{
// GetClosestDisplayMode will fail if we request a size larger
// than the largest available display mode, so we'll try to use
// the largest (first) mode in that case.
if (SDL_GetDisplayMode(f.display, 0, &mode) < 0)
return false;
}
width = mode.w;
height = mode.h;
}
}
if (f.resizable)
sdlflags |= SDL_WINDOW_RESIZABLE;
if (f.borderless)
sdlflags |= SDL_WINDOW_BORDERLESS;
if (f.highdpi)
sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
int x = f.x;
int y = f.y;
@@ -567,10 +513,81 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
}
close();
SDL_DisplayMode fsmode = {0, width, height, 0, nullptr};
if (!createWindowAndContext(x, y, width, height, sdlflags, renderer, f.msaa, f.stencil, f.depth))
return false;
if (f.fullscreen && f.fstype == FULLSCREEN_EXCLUSIVE)
{
// Fullscreen window creation will bug out if no mode can be used.
if (SDL_GetClosestDisplayMode(f.display, &fsmode, &fsmode) == nullptr)
{
// GetClosestDisplayMode will fail if we request a size larger
// than the largest available display mode, so we'll try to use
// the largest (first) mode in that case.
if (SDL_GetDisplayMode(f.display, 0, &fsmode) < 0)
return false;
}
}
bool needsetmode = false;
Uint32 sdlflags = 0;
if (f.fullscreen)
{
if (f.fstype == FULLSCREEN_DESKTOP)
sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
else
{
sdlflags |= SDL_WINDOW_FULLSCREEN;
width = fsmode.w;
height = fsmode.h;
}
}
if (renderer == graphics::Graphics::RENDERER_OPENGL)
sdlflags |= SDL_WINDOW_OPENGL;
#ifdef LOVE_GRAPHICS_METAL
if (renderer == graphics::Graphics::RENDERER_METAL)
sdlflags |= SDL_WINDOW_METAL;
#endif
if (isOpen())
{
if (SDL_SetWindowFullscreen(window, sdlflags) == 0 && renderer == graphics::Graphics::RENDERER_OPENGL)
SDL_GL_MakeCurrent(window, glcontext);
if (!f.fullscreen)
SDL_SetWindowSize(window, width, height);
// On linux systems 2.0.5+ might not be available...
// TODO: require at least 2.0.5?
#if SDL_VERSION_ATLEAST(2, 0, 5)
if (this->settings.resizable != f.resizable)
SDL_SetWindowResizable(window, f.resizable ? SDL_TRUE : SDL_FALSE);
#endif
if (this->settings.borderless != f.borderless)
SDL_SetWindowBordered(window, f.borderless ? SDL_FALSE : SDL_TRUE);
}
else
{
sdlflags |= SDL_WINDOW_OPENGL;
if (f.resizable)
sdlflags |= SDL_WINDOW_RESIZABLE;
if (f.borderless)
sdlflags |= SDL_WINDOW_BORDERLESS;
if (isHighDPIAllowed())
sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
if (!createWindowAndContext(x, y, width, height, sdlflags, renderer))
return false;
needsetmode = true;
}
// Make sure the window keeps any previously set icon.
setIcon(icon.get());
@@ -581,7 +598,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
// Enforce minimum window dimensions.
SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
if ((f.useposition || f.centered) && !f.fullscreen)
if (this->settings.display != f.display || ((f.useposition || f.centered) && !f.fullscreen))
SDL_SetWindowPosition(window, x, y);
SDL_RaiseWindow(window);
@@ -595,15 +612,23 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
double scaledw, scaledh;
fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh);
void *context = nullptr;
if (renderer == graphics::Graphics::RENDERER_OPENGL)
context = (void *) glcontext;
if (needsetmode)
{
void *context = nullptr;
if (renderer == graphics::Graphics::RENDERER_OPENGL)
context = (void *) glcontext;
#ifdef LOVE_GRAPHICS_METAL
if (renderer == graphics::Graphics::RENDERER_METAL && metalView)
context = (void *) SDL_Metal_GetLayer(metalView);
if (renderer == graphics::Graphics::RENDERER_METAL && metalView)
context = (void *) SDL_Metal_GetLayer(metalView);
#endif
graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth);
graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.msaa);
this->settings.msaa = graphics->getBackbufferMSAA();
}
else
{
graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight);
}
}
#ifdef LOVE_ANDROID
@@ -680,7 +705,8 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi
getPosition(settings.x, settings.y, settings.display);
settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
setHighDPIAllowed((wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0);
settings.usedpiscale = newsettings.usedpiscale;
// Only minimize on focus loss if the window is in exclusive-fullscreen mode
@@ -689,17 +715,6 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi
else
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
// Verify MSAA setting.
int buffers = 0;
int samples = 0;
if ((wflags & SDL_WINDOW_OPENGL) != 0)
{
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
}
settings.msaa = (buffers > 0 ? samples : 0);
settings.vsync = getVSync();
settings.stencil = newsettings.stencil;
@@ -773,7 +788,7 @@ void Window::close(bool allowExceptions)
open = false;
}
bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
bool Window::setFullscreen(bool fullscreen, FullscreenType fstype)
{
if (!window)
return false;
@@ -812,9 +827,10 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
{
if (glcontext)
SDL_GL_MakeCurrent(window, glcontext);
updateSettings(newsettings, true);
// Apparently this gets un-set when we exit fullscreen (at least in macOS).
// This gets un-set when we exit fullscreen (at least in macOS).
if (!fullscreen)
SDL_SetWindowMinimumSize(window, settings.minwidth, settings.minheight);
+4 -4
View File
@@ -131,8 +131,6 @@ public:
private:
void close(bool allowExceptions);
struct ContextAttribs
{
int versionMajor;
@@ -141,11 +139,13 @@ private:
bool debug;
};
void setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth);
void close(bool allowExceptions);
void setGLFramebufferAttributes(bool sRGB);
void setGLContextAttributes(const ContextAttribs &attribs);
bool checkGLVersion(const ContextAttribs &attribs, std::string &outversion);
std::vector<ContextAttribs> getContextAttribsList() const;
bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer, int msaa, bool stencil, int depth);
bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer);
// Update the saved window settings based on the window's actual state.
void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport);
+18 -4
View File
@@ -75,9 +75,19 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings)
settings.borderless = luax_boolflag(L, idx, settingName(Window::SETTING_BORDERLESS), settings.borderless);
settings.centered = luax_boolflag(L, idx, settingName(Window::SETTING_CENTERED), settings.centered);
settings.display = luax_intflag(L, idx, settingName(Window::SETTING_DISPLAY), settings.display+1) - 1;
settings.highdpi = luax_boolflag(L, idx, settingName(Window::SETTING_HIGHDPI), settings.highdpi);
settings.usedpiscale = luax_boolflag(L, idx, settingName(Window::SETTING_USE_DPISCALE), settings.usedpiscale);
lua_getfield(L, idx, settingName(Window::SETTING_HIGHDPI));
if (!lua_isnoneornil(L, -1))
{
luax_markdeprecated(L, "window.highdpi", API_FIELD, DEPRECATED_REPLACED, "t.highdpi in love.conf");
bool highdpi = luax_checkboolean(L, -1);
if (!instance()->isOpen())
setHighDPIAllowed(highdpi);
}
lua_pop(L, 1);
lua_getfield(L, idx, settingName(Window::SETTING_VSYNC));
if (lua_isnumber(L, -1))
settings.vsync = (int) lua_tointeger(L, -1);
@@ -201,9 +211,6 @@ int w_getMode(lua_State *L)
lua_pushinteger(L, settings.display + 1);
lua_setfield(L, -2, settingName(Window::SETTING_DISPLAY));
luax_pushboolean(L, settings.highdpi);
lua_setfield(L, -2, settingName(Window::SETTING_HIGHDPI));
luax_pushboolean(L, settings.usedpiscale);
lua_setfield(L, -2, settingName(Window::SETTING_USE_DPISCALE));
@@ -219,6 +226,12 @@ int w_getMode(lua_State *L)
return 3;
}
int w_isHighDPIAllowed(lua_State *L)
{
luax_pushboolean(L, isHighDPIAllowed());
return 1;
}
int w_getDisplayOrientation(lua_State *L)
{
int displayindex = 0;
@@ -618,6 +631,7 @@ static const luaL_Reg functions[] =
{ "setMode", w_setMode },
{ "updateMode", w_updateMode },
{ "getMode", w_getMode },
{ "isHighDPIAllowed", w_isHighDPIAllowed },
{ "getDisplayOrientation", w_getDisplayOrientation },
{ "getFullscreenModes", w_getFullscreenModes },
{ "setFullscreen", w_setFullscreen },