mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +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(); }
|
||||
#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);
|
||||
|
||||
@@ -118,7 +141,7 @@ Graphics *Graphics::createInstance(const std::vector<Renderer> &renderers)
|
||||
instance->retain();
|
||||
else
|
||||
{
|
||||
for (auto renderer : renderers)
|
||||
for (auto renderer : _renderers)
|
||||
{
|
||||
if (renderer == RENDERER_OPENGL)
|
||||
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_BEGIN(Renderer, RENDERER_MAX_ENUM, renderer)
|
||||
{
|
||||
{ "opengl", RENDERER_OPENGL },
|
||||
{ "metal", RENDERER_METAL },
|
||||
}
|
||||
STRINGMAP_END(Renderer, RENDERER_MAX_ENUM, renderer)
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -65,6 +65,14 @@ typedef Optional<ColorD> OptionalColorD;
|
||||
|
||||
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
|
||||
* prior to using any Graphics module function.
|
||||
@@ -95,6 +103,10 @@ Colorf unGammaCorrectColor(const Colorf &c);
|
||||
|
||||
bool isDebugEnabled();
|
||||
|
||||
const std::vector<Renderer> &getDefaultRenderers();
|
||||
const std::vector<Renderer> &getRenderers();
|
||||
void setRenderers(const std::vector<Renderer> &renderers);
|
||||
|
||||
class Graphics : public Module
|
||||
{
|
||||
public:
|
||||
@@ -151,14 +163,6 @@ public:
|
||||
FEATURE_MAX_ENUM
|
||||
};
|
||||
|
||||
enum Renderer
|
||||
{
|
||||
RENDERER_NONE,
|
||||
RENDERER_OPENGL,
|
||||
RENDERER_METAL,
|
||||
RENDERER_MAX_ENUM
|
||||
};
|
||||
|
||||
enum SystemLimit
|
||||
{
|
||||
LIMIT_POINT_SIZE,
|
||||
@@ -860,7 +864,7 @@ public:
|
||||
return (T *) scratchBuffer.data();
|
||||
}
|
||||
|
||||
static Graphics *createInstance(const std::vector<Renderer> &renderers);
|
||||
static Graphics *createInstance();
|
||||
|
||||
STRINGMAP_CLASS_DECLARE(DrawMode);
|
||||
STRINGMAP_CLASS_DECLARE(ArcMode);
|
||||
@@ -1016,6 +1020,8 @@ private:
|
||||
|
||||
}; // Graphics
|
||||
|
||||
STRINGMAP_DECLARE(Renderer);
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
|
||||
@@ -2016,7 +2016,7 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, PixelFormatUsageFlags
|
||||
return (usage & flags) == usage;
|
||||
}
|
||||
|
||||
Graphics::Renderer Graphics::getRenderer() const
|
||||
Renderer Graphics::getRenderer() const
|
||||
{
|
||||
return RENDERER_METAL;
|
||||
}
|
||||
|
||||
@@ -1599,7 +1599,7 @@ void Graphics::releaseBufferMapMemory(void *mem)
|
||||
free(mem);
|
||||
}
|
||||
|
||||
Graphics::Renderer Graphics::getRenderer() const
|
||||
Renderer Graphics::getRenderer() const
|
||||
{
|
||||
return RENDERER_OPENGL;
|
||||
}
|
||||
|
||||
@@ -3697,16 +3697,7 @@ static const lua_CFunction types[] =
|
||||
|
||||
extern "C" int luaopen_love_graphics(lua_State *L)
|
||||
{
|
||||
Graphics *instance = nullptr;
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
Graphics *instance = Graphics::createInstance();
|
||||
|
||||
if (instance == nullptr)
|
||||
{
|
||||
|
||||
@@ -114,8 +114,10 @@ end
|
||||
|
||||
love.arg.options = {
|
||||
console = { a = 0 },
|
||||
fused = {a = 0 },
|
||||
game = { a = 1 }
|
||||
fused = { a = 0 },
|
||||
game = { a = 1 },
|
||||
renderers = { a = 1 },
|
||||
excluderenderers = { a = 1 },
|
||||
}
|
||||
|
||||
love.arg.optionIndices = {}
|
||||
|
||||
@@ -184,6 +184,8 @@ function love.init()
|
||||
accelerometerjoystick = true, -- Only relevant for Android / iOS.
|
||||
gammacorrect = false,
|
||||
highdpi = false,
|
||||
renderers = nil,
|
||||
excluderenderers = nil,
|
||||
}
|
||||
|
||||
-- Console hack, part 1.
|
||||
@@ -221,6 +223,45 @@ function love.init()
|
||||
love._setGammaCorrect(c.gammacorrect)
|
||||
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
|
||||
love._setHighDPIAllowed(c.highdpi)
|
||||
end
|
||||
|
||||
@@ -356,6 +356,75 @@ static int w__setGammaCorrect(lua_State *L)
|
||||
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)
|
||||
{
|
||||
#ifdef LOVE_ENABLE_WINDOW
|
||||
@@ -491,6 +560,15 @@ int luaopen_love(lua_State *L)
|
||||
lua_pushcfunction(L, w__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_setfield(L, -2, "_setHighDPIAllowed");
|
||||
|
||||
|
||||
@@ -295,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)
|
||||
bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Renderer renderer)
|
||||
{
|
||||
bool needsglcontext = (windowflags & SDL_WINDOW_OPENGL) != 0;
|
||||
#ifdef LOVE_GRAPHICS_METAL
|
||||
@@ -368,7 +368,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
|
||||
return true;
|
||||
};
|
||||
|
||||
if (renderer == graphics::Graphics::RENDERER_OPENGL)
|
||||
if (renderer == graphics::RENDERER_OPENGL)
|
||||
{
|
||||
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
|
||||
else if (renderer == graphics::Graphics::RENDERER_METAL)
|
||||
else if (renderer == graphics::RENDERER_METAL)
|
||||
{
|
||||
if (create(nullptr) && window != nullptr)
|
||||
metalView = SDL_Metal_CreateView(window);
|
||||
@@ -465,7 +465,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
if (graphics.get() && graphics->isRenderTargetActive())
|
||||
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())
|
||||
updateSettings(this->settings, false);
|
||||
@@ -557,7 +557,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
|
||||
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);
|
||||
|
||||
if (!f.fullscreen)
|
||||
@@ -575,11 +575,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (renderer == graphics::Graphics::RENDERER_OPENGL)
|
||||
if (renderer == graphics::RENDERER_OPENGL)
|
||||
sdlflags |= SDL_WINDOW_OPENGL;
|
||||
|
||||
#ifdef LOVE_GRAPHICS_METAL
|
||||
if (renderer == graphics::Graphics::RENDERER_METAL)
|
||||
if (renderer == graphics::RENDERER_METAL)
|
||||
sdlflags |= SDL_WINDOW_METAL;
|
||||
#endif
|
||||
|
||||
@@ -626,10 +626,10 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
if (needsetmode)
|
||||
{
|
||||
void *context = nullptr;
|
||||
if (renderer == graphics::Graphics::RENDERER_OPENGL)
|
||||
if (renderer == graphics::RENDERER_OPENGL)
|
||||
context = (void *) glcontext;
|
||||
#ifdef LOVE_GRAPHICS_METAL
|
||||
if (renderer == graphics::Graphics::RENDERER_METAL && metalView)
|
||||
if (renderer == graphics::RENDERER_METAL && metalView)
|
||||
context = (void *) SDL_Metal_GetLayer(metalView);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ private:
|
||||
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);
|
||||
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.
|
||||
void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport);
|
||||
@@ -172,7 +172,7 @@ private:
|
||||
SDL_MetalView metalView;
|
||||
#endif
|
||||
|
||||
graphics::Graphics::Renderer windowRenderer = graphics::Graphics::RENDERER_NONE;
|
||||
graphics::Renderer windowRenderer = graphics::RENDERER_NONE;
|
||||
|
||||
bool displayedWindowError;
|
||||
bool hasSDL203orEarlier;
|
||||
|
||||
Reference in New Issue
Block a user