mirror of
https://github.com/love2d/love.git
synced 2026-08-20 12:40:20 +02:00
Add ability to configure which renderers are used by love.graphics.
- Add t.renderers and t.excluderenderers love.conf fields. They can be an array of renderer names. - Add --renderers a,list,of,renderernames and --excluderenderers more,renderers argument options.
This commit is contained in:
@@ -110,7 +110,30 @@ namespace opengl { extern love::graphics::Graphics *createInstance(); }
|
|||||||
namespace metal { extern love::graphics::Graphics *createInstance(); }
|
namespace metal { extern love::graphics::Graphics *createInstance(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Graphics *Graphics::createInstance(const std::vector<Renderer> &renderers)
|
static std::vector<Renderer> defaultRenderers =
|
||||||
|
{
|
||||||
|
RENDERER_METAL,
|
||||||
|
RENDERER_OPENGL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<Renderer> _renderers = defaultRenderers;
|
||||||
|
|
||||||
|
const std::vector<Renderer> &getDefaultRenderers()
|
||||||
|
{
|
||||||
|
return defaultRenderers;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<Renderer> &getRenderers()
|
||||||
|
{
|
||||||
|
return _renderers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRenderers(const std::vector<Renderer> &renderers)
|
||||||
|
{
|
||||||
|
_renderers = renderers;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics *Graphics::createInstance()
|
||||||
{
|
{
|
||||||
Graphics *instance = Module::getInstance<Graphics>(M_GRAPHICS);
|
Graphics *instance = Module::getInstance<Graphics>(M_GRAPHICS);
|
||||||
|
|
||||||
@@ -118,7 +141,7 @@ Graphics *Graphics::createInstance(const std::vector<Renderer> &renderers)
|
|||||||
instance->retain();
|
instance->retain();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto renderer : renderers)
|
for (auto renderer : _renderers)
|
||||||
{
|
{
|
||||||
if (renderer == RENDERER_OPENGL)
|
if (renderer == RENDERER_OPENGL)
|
||||||
instance = opengl::createInstance();
|
instance = opengl::createInstance();
|
||||||
@@ -2147,5 +2170,12 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::StackType, Graphics::STACK_MAX_ENUM, s
|
|||||||
}
|
}
|
||||||
STRINGMAP_CLASS_END(Graphics, Graphics::StackType, Graphics::STACK_MAX_ENUM, stackType)
|
STRINGMAP_CLASS_END(Graphics, Graphics::StackType, Graphics::STACK_MAX_ENUM, stackType)
|
||||||
|
|
||||||
|
STRINGMAP_BEGIN(Renderer, RENDERER_MAX_ENUM, renderer)
|
||||||
|
{
|
||||||
|
{ "opengl", RENDERER_OPENGL },
|
||||||
|
{ "metal", RENDERER_METAL },
|
||||||
|
}
|
||||||
|
STRINGMAP_END(Renderer, RENDERER_MAX_ENUM, renderer)
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -65,6 +65,14 @@ typedef Optional<ColorD> OptionalColorD;
|
|||||||
|
|
||||||
const int MAX_COLOR_RENDER_TARGETS = 8;
|
const int MAX_COLOR_RENDER_TARGETS = 8;
|
||||||
|
|
||||||
|
enum Renderer
|
||||||
|
{
|
||||||
|
RENDERER_NONE,
|
||||||
|
RENDERER_OPENGL,
|
||||||
|
RENDERER_METAL,
|
||||||
|
RENDERER_MAX_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Globally sets whether gamma correction is enabled. Ideally this should be set
|
* Globally sets whether gamma correction is enabled. Ideally this should be set
|
||||||
* prior to using any Graphics module function.
|
* prior to using any Graphics module function.
|
||||||
@@ -95,6 +103,10 @@ Colorf unGammaCorrectColor(const Colorf &c);
|
|||||||
|
|
||||||
bool isDebugEnabled();
|
bool isDebugEnabled();
|
||||||
|
|
||||||
|
const std::vector<Renderer> &getDefaultRenderers();
|
||||||
|
const std::vector<Renderer> &getRenderers();
|
||||||
|
void setRenderers(const std::vector<Renderer> &renderers);
|
||||||
|
|
||||||
class Graphics : public Module
|
class Graphics : public Module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -151,14 +163,6 @@ public:
|
|||||||
FEATURE_MAX_ENUM
|
FEATURE_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Renderer
|
|
||||||
{
|
|
||||||
RENDERER_NONE,
|
|
||||||
RENDERER_OPENGL,
|
|
||||||
RENDERER_METAL,
|
|
||||||
RENDERER_MAX_ENUM
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SystemLimit
|
enum SystemLimit
|
||||||
{
|
{
|
||||||
LIMIT_POINT_SIZE,
|
LIMIT_POINT_SIZE,
|
||||||
@@ -860,7 +864,7 @@ public:
|
|||||||
return (T *) scratchBuffer.data();
|
return (T *) scratchBuffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Graphics *createInstance(const std::vector<Renderer> &renderers);
|
static Graphics *createInstance();
|
||||||
|
|
||||||
STRINGMAP_CLASS_DECLARE(DrawMode);
|
STRINGMAP_CLASS_DECLARE(DrawMode);
|
||||||
STRINGMAP_CLASS_DECLARE(ArcMode);
|
STRINGMAP_CLASS_DECLARE(ArcMode);
|
||||||
@@ -1016,6 +1020,8 @@ private:
|
|||||||
|
|
||||||
}; // Graphics
|
}; // Graphics
|
||||||
|
|
||||||
|
STRINGMAP_DECLARE(Renderer);
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
@@ -2016,7 +2016,7 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, PixelFormatUsageFlags
|
|||||||
return (usage & flags) == usage;
|
return (usage & flags) == usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Renderer Graphics::getRenderer() const
|
Renderer Graphics::getRenderer() const
|
||||||
{
|
{
|
||||||
return RENDERER_METAL;
|
return RENDERER_METAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1599,7 +1599,7 @@ void Graphics::releaseBufferMapMemory(void *mem)
|
|||||||
free(mem);
|
free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Renderer Graphics::getRenderer() const
|
Renderer Graphics::getRenderer() const
|
||||||
{
|
{
|
||||||
return RENDERER_OPENGL;
|
return RENDERER_OPENGL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3697,16 +3697,7 @@ static const lua_CFunction types[] =
|
|||||||
|
|
||||||
extern "C" int luaopen_love_graphics(lua_State *L)
|
extern "C" int luaopen_love_graphics(lua_State *L)
|
||||||
{
|
{
|
||||||
Graphics *instance = nullptr;
|
Graphics *instance = Graphics::createInstance();
|
||||||
|
|
||||||
{
|
|
||||||
std::vector<Graphics::Renderer> renderers;
|
|
||||||
#if defined(LOVE_MACOS) || defined(LOVE_IOS)
|
|
||||||
renderers.push_back(Graphics::RENDERER_METAL);
|
|
||||||
#endif
|
|
||||||
renderers.push_back(Graphics::RENDERER_OPENGL);
|
|
||||||
instance = Graphics::createInstance(renderers);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance == nullptr)
|
if (instance == nullptr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -114,8 +114,10 @@ end
|
|||||||
|
|
||||||
love.arg.options = {
|
love.arg.options = {
|
||||||
console = { a = 0 },
|
console = { a = 0 },
|
||||||
fused = {a = 0 },
|
fused = { a = 0 },
|
||||||
game = { a = 1 }
|
game = { a = 1 },
|
||||||
|
renderers = { a = 1 },
|
||||||
|
excluderenderers = { a = 1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
love.arg.optionIndices = {}
|
love.arg.optionIndices = {}
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ function love.init()
|
|||||||
accelerometerjoystick = true, -- Only relevant for Android / iOS.
|
accelerometerjoystick = true, -- Only relevant for Android / iOS.
|
||||||
gammacorrect = false,
|
gammacorrect = false,
|
||||||
highdpi = false,
|
highdpi = false,
|
||||||
|
renderers = nil,
|
||||||
|
excluderenderers = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Console hack, part 1.
|
-- Console hack, part 1.
|
||||||
@@ -221,6 +223,45 @@ function love.init()
|
|||||||
love._setGammaCorrect(c.gammacorrect)
|
love._setGammaCorrect(c.gammacorrect)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if love._setRenderers then
|
||||||
|
local renderers = love._getDefaultRenderers()
|
||||||
|
if type(c.renderers) == "table" then
|
||||||
|
renderers = {}
|
||||||
|
for i,v in ipairs(c.renderers) do
|
||||||
|
renderers[i] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if love.arg.options.renderers.set then
|
||||||
|
local renderersstr = love.arg.options.renderers.arg[1]
|
||||||
|
renderers = {}
|
||||||
|
for r in renderersstr:gmatch("[^,]+") do
|
||||||
|
table.insert(renderers, r)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local excluderenderers = c.excluderenderers
|
||||||
|
if love.arg.options.excluderenderers.set then
|
||||||
|
local excludestr = love.arg.options.excluderenderers.arg[1]
|
||||||
|
excluderenderers = {}
|
||||||
|
for r in excludestr:gmatch("[^,]+") do
|
||||||
|
table.insert(excluderenderers, r)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(excluderenderers) == "table" then
|
||||||
|
for i,v in ipairs(excluderenderers) do
|
||||||
|
for j=#renderers, 1, -1 do
|
||||||
|
if renderers[j] == v then
|
||||||
|
table.remove(renderers, j)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love._setRenderers(renderers)
|
||||||
|
end
|
||||||
|
|
||||||
if love._setHighDPIAllowed then
|
if love._setHighDPIAllowed then
|
||||||
love._setHighDPIAllowed(c.highdpi)
|
love._setHighDPIAllowed(c.highdpi)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -356,6 +356,75 @@ static int w__setGammaCorrect(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int w__getDefaultRenderers(lua_State *L)
|
||||||
|
{
|
||||||
|
#ifdef LOVE_ENABLE_GRAPHICS
|
||||||
|
const auto &renderers = love::graphics::getDefaultRenderers();
|
||||||
|
|
||||||
|
lua_createtable(L, (int) renderers.size(), 0);
|
||||||
|
|
||||||
|
int n = 1;
|
||||||
|
for (auto r : renderers)
|
||||||
|
{
|
||||||
|
const char *str = nullptr;
|
||||||
|
if (love::graphics::getConstant(r, str))
|
||||||
|
{
|
||||||
|
lua_pushstring(L, str);
|
||||||
|
lua_rawseti(L, -2, n++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
lua_createtable(L, 0, 0);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int w__getRenderers(lua_State *L)
|
||||||
|
{
|
||||||
|
#ifdef LOVE_ENABLE_GRAPHICS
|
||||||
|
const auto &renderers = love::graphics::getRenderers();
|
||||||
|
|
||||||
|
lua_createtable(L, (int) renderers.size(), 0);
|
||||||
|
|
||||||
|
int n = 1;
|
||||||
|
for (auto r : renderers)
|
||||||
|
{
|
||||||
|
const char *str = nullptr;
|
||||||
|
if (love::graphics::getConstant(r, str))
|
||||||
|
{
|
||||||
|
lua_pushstring(L, str);
|
||||||
|
lua_rawseti(L, -2, n++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
lua_createtable(L, 0, 0);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int w__setRenderers(lua_State *L)
|
||||||
|
{
|
||||||
|
#ifdef LOVE_ENABLE_GRAPHICS
|
||||||
|
std::vector<love::graphics::Renderer> renderers;
|
||||||
|
|
||||||
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
for (size_t i = 1; i <= love::luax_objlen(L, 1); i++)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, -1, (int) i);
|
||||||
|
const char *str = luaL_checkstring(L, -1);
|
||||||
|
|
||||||
|
love::graphics::Renderer r;
|
||||||
|
if (love::graphics::getConstant(str, r))
|
||||||
|
renderers.push_back(r);
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
love::graphics::setRenderers(renderers);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int w__setHighDPIAllowed(lua_State *L)
|
static int w__setHighDPIAllowed(lua_State *L)
|
||||||
{
|
{
|
||||||
#ifdef LOVE_ENABLE_WINDOW
|
#ifdef LOVE_ENABLE_WINDOW
|
||||||
@@ -491,6 +560,15 @@ int luaopen_love(lua_State *L)
|
|||||||
lua_pushcfunction(L, w__setGammaCorrect);
|
lua_pushcfunction(L, w__setGammaCorrect);
|
||||||
lua_setfield(L, -2, "_setGammaCorrect");
|
lua_setfield(L, -2, "_setGammaCorrect");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, w__getDefaultRenderers);
|
||||||
|
lua_setfield(L, -2, "_getDefaultRenderers");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, w__getRenderers);
|
||||||
|
lua_setfield(L, -2, "_getRenderers");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, w__setRenderers);
|
||||||
|
lua_setfield(L, -2, "_setRenderers");
|
||||||
|
|
||||||
lua_pushcfunction(L, w__setHighDPIAllowed);
|
lua_pushcfunction(L, w__setHighDPIAllowed);
|
||||||
lua_setfield(L, -2, "_setHighDPIAllowed");
|
lua_setfield(L, -2, "_setHighDPIAllowed");
|
||||||
|
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
|
|||||||
return attribslist;
|
return attribslist;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer)
|
bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Renderer renderer)
|
||||||
{
|
{
|
||||||
bool needsglcontext = (windowflags & SDL_WINDOW_OPENGL) != 0;
|
bool needsglcontext = (windowflags & SDL_WINDOW_OPENGL) != 0;
|
||||||
#ifdef LOVE_GRAPHICS_METAL
|
#ifdef LOVE_GRAPHICS_METAL
|
||||||
@@ -368,7 +368,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (renderer == graphics::Graphics::RENDERER_OPENGL)
|
if (renderer == graphics::RENDERER_OPENGL)
|
||||||
{
|
{
|
||||||
std::vector<ContextAttribs> attribslist = getContextAttribsList();
|
std::vector<ContextAttribs> attribslist = getContextAttribsList();
|
||||||
|
|
||||||
@@ -404,7 +404,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef LOVE_GRAPHICS_METAL
|
#ifdef LOVE_GRAPHICS_METAL
|
||||||
else if (renderer == graphics::Graphics::RENDERER_METAL)
|
else if (renderer == graphics::RENDERER_METAL)
|
||||||
{
|
{
|
||||||
if (create(nullptr) && window != nullptr)
|
if (create(nullptr) && window != nullptr)
|
||||||
metalView = SDL_Metal_CreateView(window);
|
metalView = SDL_Metal_CreateView(window);
|
||||||
@@ -465,7 +465,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
if (graphics.get() && graphics->isRenderTargetActive())
|
if (graphics.get() && graphics->isRenderTargetActive())
|
||||||
throw love::Exception("love.window.setMode cannot be called while a render target is active in love.graphics.");
|
throw love::Exception("love.window.setMode cannot be called while a render target is active in love.graphics.");
|
||||||
|
|
||||||
auto renderer = graphics != nullptr ? graphics->getRenderer() : graphics::Graphics::RENDERER_NONE;
|
auto renderer = graphics != nullptr ? graphics->getRenderer() : graphics::RENDERER_NONE;
|
||||||
|
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
updateSettings(this->settings, false);
|
updateSettings(this->settings, false);
|
||||||
@@ -557,7 +557,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
|
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
{
|
{
|
||||||
if (SDL_SetWindowFullscreen(window, sdlflags) == 0 && renderer == graphics::Graphics::RENDERER_OPENGL)
|
if (SDL_SetWindowFullscreen(window, sdlflags) == 0 && renderer == graphics::RENDERER_OPENGL)
|
||||||
SDL_GL_MakeCurrent(window, glcontext);
|
SDL_GL_MakeCurrent(window, glcontext);
|
||||||
|
|
||||||
if (!f.fullscreen)
|
if (!f.fullscreen)
|
||||||
@@ -575,11 +575,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (renderer == graphics::Graphics::RENDERER_OPENGL)
|
if (renderer == graphics::RENDERER_OPENGL)
|
||||||
sdlflags |= SDL_WINDOW_OPENGL;
|
sdlflags |= SDL_WINDOW_OPENGL;
|
||||||
|
|
||||||
#ifdef LOVE_GRAPHICS_METAL
|
#ifdef LOVE_GRAPHICS_METAL
|
||||||
if (renderer == graphics::Graphics::RENDERER_METAL)
|
if (renderer == graphics::RENDERER_METAL)
|
||||||
sdlflags |= SDL_WINDOW_METAL;
|
sdlflags |= SDL_WINDOW_METAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -626,10 +626,10 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
if (needsetmode)
|
if (needsetmode)
|
||||||
{
|
{
|
||||||
void *context = nullptr;
|
void *context = nullptr;
|
||||||
if (renderer == graphics::Graphics::RENDERER_OPENGL)
|
if (renderer == graphics::RENDERER_OPENGL)
|
||||||
context = (void *) glcontext;
|
context = (void *) glcontext;
|
||||||
#ifdef LOVE_GRAPHICS_METAL
|
#ifdef LOVE_GRAPHICS_METAL
|
||||||
if (renderer == graphics::Graphics::RENDERER_METAL && metalView)
|
if (renderer == graphics::RENDERER_METAL && metalView)
|
||||||
context = (void *) SDL_Metal_GetLayer(metalView);
|
context = (void *) SDL_Metal_GetLayer(metalView);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ private:
|
|||||||
void setGLContextAttributes(const ContextAttribs &attribs);
|
void setGLContextAttributes(const ContextAttribs &attribs);
|
||||||
bool checkGLVersion(const ContextAttribs &attribs, std::string &outversion);
|
bool checkGLVersion(const ContextAttribs &attribs, std::string &outversion);
|
||||||
std::vector<ContextAttribs> getContextAttribsList() const;
|
std::vector<ContextAttribs> getContextAttribsList() const;
|
||||||
bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer);
|
bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Renderer renderer);
|
||||||
|
|
||||||
// Update the saved window settings based on the window's actual state.
|
// Update the saved window settings based on the window's actual state.
|
||||||
void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport);
|
void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport);
|
||||||
@@ -172,7 +172,7 @@ private:
|
|||||||
SDL_MetalView metalView;
|
SDL_MetalView metalView;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
graphics::Graphics::Renderer windowRenderer = graphics::Graphics::RENDERER_NONE;
|
graphics::Renderer windowRenderer = graphics::RENDERER_NONE;
|
||||||
|
|
||||||
bool displayedWindowError;
|
bool displayedWindowError;
|
||||||
bool hasSDL203orEarlier;
|
bool hasSDL203orEarlier;
|
||||||
|
|||||||
Reference in New Issue
Block a user