diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 08a9a39d68..f337d5c3e0 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -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) { } - diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 3551953998..7546484cc3 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -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; diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 938ed77730..f124770cfb 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -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) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index d619d0afee..3f760e4cc8 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -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, ¤tMode); + _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) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index c51ca9682a..2d0c6ec735 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -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;