Add OpenGL state cache to save some redundant state change.

This commit is contained in:
Florent Castelli 2012-11-24 15:19:08 +01:00
parent 84f741b21d
commit 8900d99779
8 changed files with 156 additions and 14 deletions

View File

@ -38,6 +38,7 @@ LOCAL_SRC_FILES :=\
net/resolve.cpp \
profiler/profiler.cpp \
gfx_es2/glsl_program.cpp \
gfx_es2/gl_state.cpp \
gfx_es2/draw_buffer.cpp.arm \
gfx_es2/vertex_format.cpp \
gfx_es2/fbo.cpp \

View File

@ -2,6 +2,7 @@ set(SRCS
draw_buffer.cpp
fbo.cpp
glsl_program.cpp
gl_state.cpp
vertex_format.cpp)
set(SRCS ${SRCS})

View File

@ -18,6 +18,7 @@
#include "math/math_util.h"
#include "gfx_es2/draw_buffer.h"
#include "gfx_es2/glsl_program.h"
#include "gfx_es2/gl_state.h"
#include "gfx/texture_atlas.h"
#include "gfx/gl_debug_log.h"
@ -50,8 +51,8 @@ void DrawBuffer::Flush(const GLSLProgram *program, bool set_blend_state) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (set_blend_state) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glstate.blend.enable();
glstate.blendFunc.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glUniform1i(program->sampler0, 0);
glEnableVertexAttribArray(program->a_position);
@ -357,13 +358,8 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co
}
void DrawBuffer::EnableBlend(bool enable) {
if (enable)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
glDisable(GL_BLEND);
glstate.blend.set(enable);
glstate.blendFunc.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void DrawBuffer::SetClipRect(float x, float y, float w, float h)

23
gfx_es2/gl_state.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "gl_state.h"
OpenGLState glstate;
void OpenGLState::Initialize() {
if(initialized) return;
Restore();
initialized = true;
}
void OpenGLState::Restore() {
blend.restore();
blendEquation.restore();
blendFunc.restore();
cullFace.restore();
cullFaceMode.restore();
depthTest.restore();
depthFunc.restore();
}

112
gfx_es2/gl_state.h Normal file
View File

@ -0,0 +1,112 @@
#pragma once
#if defined(ANDROID) || defined(BLACKBERRY)
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#else
#include <GL/glew.h>
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#endif
#include <functional>
class OpenGLState
{
private:
template<GLenum cap, bool init>
class BoolState {
bool _value;
public:
BoolState() : _value(init) {}
inline void set(bool value) {
if(value && value != _value) {
_value = value;
glEnable(cap);
}
if(!value && value != _value) {
_value = value;
glDisable(cap);
}
}
inline void enable() {
set(true);
}
inline void disable() {
set(false);
}
operator bool() const {
return isset();
}
inline bool isset() {
return _value;
}
void restore() {
if(_value)
glEnable(cap);
else
glDisable(cap);
}
};
#define STATE1(func, p1type, p1def) \
class SavedState1_##func { \
p1type p1; \
public: \
SavedState1_##func() : p1(p1def) {}; \
void set(p1type newp1) { \
if(newp1 != p1) { \
p1 = newp1; \
##func(p1); \
} \
} \
void restore() { \
##func(p1); \
} \
}
#define STATE2(func, p1type, p2type, p1def, p2def) \
class SavedState2_##func { \
p1type p1; \
p2type p2; \
public: \
SavedState2_##func() : p1(p1def), p2(p2def) {}; \
inline void set(p1type newp1, p2type newp2) { \
if(newp1 != p1 || newp2 != p2) { \
p1 = newp1; \
p2 = newp2; \
##func(p1, p2); \
} \
} \
inline void restore() { \
##func(p1, p2); \
} \
}
bool initialized;
public:
OpenGLState() : initialized(false) {}
void Initialize();
void Restore();
BoolState<GL_BLEND, false> blend;
STATE2(glBlendFunc, GLenum, GLenum, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) blendFunc;
STATE1(glBlendEquation, GLenum, GL_FUNC_ADD) blendEquation;
BoolState<GL_CULL_FACE, false> cullFace;
STATE1(glCullFace, GLenum, GL_FRONT) cullFaceMode;
BoolState<GL_DEPTH_TEST, false> depthTest;
STATE1(glDepthFunc, GLenum, GL_LESS) depthFunc;
};
#undef STATE1
#undef STATE2
extern OpenGLState glstate;

View File

@ -221,6 +221,7 @@
<ClInclude Include="gfx_es2\draw_buffer.h" />
<ClInclude Include="gfx_es2\fbo.h" />
<ClInclude Include="gfx_es2\glsl_program.h" />
<ClInclude Include="gfx_es2\gl_state.h" />
<ClInclude Include="gfx_es2\vertex_format.h" />
<ClInclude Include="image\png_load.h" />
<ClInclude Include="image\zim_load.h" />
@ -310,6 +311,7 @@
<ClCompile Include="gfx_es2\draw_buffer.cpp" />
<ClCompile Include="gfx_es2\fbo.cpp" />
<ClCompile Include="gfx_es2\glsl_program.cpp" />
<ClCompile Include="gfx_es2\gl_state.cpp" />
<ClCompile Include="gfx_es2\vertex_format.cpp" />
<ClCompile Include="image\png_load.cpp" />
<ClCompile Include="image\zim_load.cpp" />

View File

@ -229,6 +229,8 @@
</ClInclude>
<ClInclude Include="ext\stb_vorbis\stb_vorbis.h">
<Filter>ext</Filter>
<ClInclude Include="gfx_es2\gl_state.h">
<Filter>gfx</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -404,6 +406,10 @@
<ClCompile Include="base\PCMain.cpp" />
<ClCompile Include="ext\stb_vorbis\stb_vorbis.c">
<Filter>ext</Filter>
<ClCompile Include="base\BlackberryMain.cpp">
<Filter>base</Filter>
<ClCompile Include="gfx_es2\gl_state.cpp">
<Filter>gfx</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@ -465,4 +471,4 @@
<UniqueIdentifier>{4515306f-4664-46bf-a89b-abfec5520a15}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>

View File

@ -3,13 +3,14 @@
#include "gfx/texture.h"
#include "gfx_es2/draw_buffer.h"
#include "gfx_es2/glsl_program.h"
#include "gfx_es2/gl_state.h"
void UIContext::Begin()
{
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glstate.blend.enable();
glstate.blendFunc.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glstate.cullFace.disable();
glstate.depthTest.disable();
if (uishader_)
glsl_bind(uishader_);
if (uitexture_)