|
|
|
@@ -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);
|
|
|
|
|
|
|
|
|
|