Introduce an official syncCache on the GLBackend to catch up with the glCOntext ttrue state

This commit is contained in:
Sam Gateau 2015-05-19 00:32:36 -07:00
parent 85fac8394a
commit 3ec6ada29d
5 changed files with 57 additions and 12 deletions

View file

@ -96,8 +96,11 @@ void GLBackend::render(Batch& batch) {
}
}
void GLBackend::renderBatch(Batch& batch) {
void GLBackend::renderBatch(Batch& batch, bool syncCache) {
GLBackend backend;
if (syncCache) {
backend.syncCache();
}
backend.render(batch);
}
@ -134,6 +137,12 @@ bool GLBackend::checkGLError(const char* name) {
}
}
void GLBackend::syncCache() {
syncTransformStateCache();
syncPipelineStateCache();
}
void GLBackend::do_draw(Batch& batch, uint32 paramOffset) {
updateInput();
updateTransform();
@ -547,4 +556,3 @@ void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) {
}

View file

@ -24,12 +24,20 @@ namespace gpu {
class GLBackend : public Backend {
public:
explicit GLBackend(bool syncCache);
GLBackend();
~GLBackend();
void render(Batch& batch);
static void renderBatch(Batch& batch);
// Render Batch create a local Context and execute the batch with it
// WARNING:
// if syncCache is true, then the gpu::GLBackend will synchornize
// its cache with the current gl state and it's BAD
// If you know you don't rely on any state changed by naked gl calls then
// leave to false where it belongs
// if true, the needed resync IS EXPENSIVE
static void renderBatch(Batch& batch, bool syncCache = true);
static bool checkGLError(const char* name = nullptr);
@ -79,6 +87,7 @@ public:
static GLShader* syncGPUObject(const Shader& shader);
static GLuint getShaderID(const ShaderPointer& shader);
// FIXME: Please remove these 2 calls once the text renderer doesn't use naked gl calls anymore
static void loadMatrix(GLenum target, const glm::mat4 & m);
static void fetchMatrix(GLenum target, glm::mat4 & m);
@ -186,6 +195,12 @@ public:
void do_setStateColorWriteMask(uint32 mask);
// This call synchronize the Full Backend cache with the current GLState
// THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync
// the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls
// Let's try to avoid to do that as much as possible!
void syncCache();
protected:
// Draw Stage
@ -241,6 +256,8 @@ protected:
void initTransform();
void killTransform();
// Synchronize the state cache of this Backend with the actual real state of the GL Context
void syncTransformStateCache();
void updateTransform();
struct TransformStageState {
TransformObject _transformObject;
@ -297,7 +314,7 @@ protected:
GLState* _state;
bool _invalidState = false;
bool _needStateSync = true;
// bool _needStateSync = true;
PipelineStageState() :
_pipeline(),
@ -306,8 +323,8 @@ protected:
_stateCache(State::DEFAULT),
_stateSignatureCache(0),
_state(nullptr),
_invalidState(false),
_needStateSync(true)
_invalidState(false)//,
// _needStateSync(true)
{}
} _pipeline;

View file

@ -64,10 +64,10 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
return;
}
if (_pipeline._needStateSync) {
/* if (_pipeline._needStateSync) {
syncPipelineStateCache();
_pipeline._needStateSync = false;
}
}*/
// null pipeline == reset
if (!pipeline) {
@ -111,12 +111,12 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
#define DEBUG_GLSTATE
void GLBackend::updatePipeline() {
#ifdef DEBUG_GLSTATE
if (_pipeline._needStateSync) {
/* if (_pipeline._needStateSync) {
State::Data state;
getCurrentGLState(state);
State::Signature signature = State::evalSignature(state);
(void) signature; // quiet compiler
}
}*/
#endif
if (_pipeline._invalidProgram) {

View file

@ -55,6 +55,25 @@ void GLBackend::killTransform() {
#else
#endif
}
void GLBackend::syncTransformStateCache() {
_transform._invalidProj = true;
_transform._invalidView = true;
_transform._invalidModel = true;
GLint currentMode;
glGetIntegerv(GL_MATRIX_MODE, &currentMode);
_transform._lastMode = currentMode;
glGetFloatv(GL_PROJECTION_MATRIX, (float*) &_transform._projection);
Mat4 modelView;
glGetFloatv(GL_MODELVIEW_MATRIX, (float*) &modelView);
auto modelViewInv = glm::inverse(modelView);
_transform._view.evalFromRawMatrix(modelViewInv);
_transform._model.setIdentity();
}
void GLBackend::updateTransform() {
// Check all the dirty flags and update the state accordingly
if (_transform._invalidProj) {

View file

@ -935,8 +935,8 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
glPushMatrix();
#endif
::gpu::GLBackend::renderBatch(batch);
::gpu::GLBackend::renderBatch(batch, true); // force sync with gl state here
#if defined(ANDROID)
#else
glPopMatrix();
@ -1846,6 +1846,7 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
}
gpu::GLBackend backend;
backend.syncCache(); // force sync with gl state here
if (args) {
glm::mat4 proj;