Added love.graphics.discard, which discards the contents of the screen (or currently active Canvas.)

Using it just after activating a Canvas can improve performance on many mobile devices, if the conditions for using it are right.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2015-02-27 04:51:38 -04:00
parent 1326ae9a5d
commit b52b9c7a2b
4 changed files with 60 additions and 17 deletions
+45 -17
View File
@@ -424,6 +424,49 @@ void Graphics::clear(Color c)
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void Graphics::discard(bool color, bool stencil)
{
if (!(GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_ES_VERSION_3_0 || GLAD_EXT_discard_framebuffer))
return;
std::vector<GLenum> attachments;
attachments.reserve(3);
// glDiscardFramebuffer uses different attachment enums for the default FBO.
if (!Canvas::current && gl.getDefaultFBO() == 0)
{
if (color)
attachments.push_back(GL_COLOR);
if (stencil)
{
attachments.push_back(GL_STENCIL);
attachments.push_back(GL_DEPTH);
}
}
else
{
if (color)
{
attachments.push_back(GL_COLOR_ATTACHMENT0);
for (int i = 0; i < (int) states.back().canvases.size() - 1; i++)
attachments.push_back(GL_COLOR_ATTACHMENT1 + i);
}
if (stencil)
{
attachments.push_back(GL_STENCIL_ATTACHMENT);
attachments.push_back(GL_DEPTH_ATTACHMENT);
}
}
// Hint for the driver that it doesn't need to save these buffers.
if (GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_ES_VERSION_3_0)
glInvalidateFramebuffer(GL_FRAMEBUFFER, (GLint) attachments.size(), &attachments[0]);
else if (GLAD_EXT_discard_framebuffer)
glDiscardFramebufferEXT(GL_FRAMEBUFFER, (GLint) attachments.size(), &attachments[0]);
}
void Graphics::present()
{
if (!isActive())
@@ -433,23 +476,8 @@ void Graphics::present()
std::vector<StrongRef<Canvas>> canvases = states.back().canvases;
setCanvas();
if (GLAD_ES_VERSION_3_0 || GLAD_EXT_discard_framebuffer)
{
GLenum attachments[] = {GL_STENCIL, GL_DEPTH};
if (gl.getDefaultFBO() != 0)
{
// A non-zero FBO needs different attachment enums.
attachments[0] = GL_STENCIL_ATTACHMENT;
attachments[1] = GL_DEPTH_ATTACHMENT;
}
// Hint for the driver that it doesn't need to save these buffers.
if (GLAD_ES_VERSION_3_0)
glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments);
else if (GLAD_EXT_discard_framebuffer)
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments);
}
// Discard the stencil buffer before swapping.
discard(false, true);
#ifdef LOVE_IOS
// Hack: SDL's color renderbuffer needs to be bound when swapBuffers is called.
+5
View File
@@ -85,6 +85,11 @@ public:
**/
void clear(Color c);
/**
* Discards the contents of the screen.
**/
void discard(bool color, bool stencil);
/**
* Flips buffers. (Rendered geometry is presented on screen).
**/
@@ -61,6 +61,14 @@ int w_clear(lua_State *L)
return 0;
}
int w_discard(lua_State *L)
{
bool color = luax_optboolean(L, 1, true);
bool stencil = luax_optboolean(L, 2, true);
instance()->discard(color, stencil);
return 0;
}
int w_present(lua_State *)
{
instance()->present();
@@ -1465,6 +1473,7 @@ static const luaL_Reg functions[] =
{
{ "reset", w_reset },
{ "clear", w_clear },
{ "discard", w_discard },
{ "present", w_present },
{ "newImage", w_newImage },
@@ -42,6 +42,7 @@ namespace opengl
int w_reset(lua_State *L);
int w_clear(lua_State *L);
int w_discard(lua_State *L);
int w_present(lua_State *L);
int w_isCreated(lua_State *L);
int w_isActive(lua_State *L);