eglSwapBuffers failure when not call windowMovedOrResized

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
longer
Kobold
Posts: 37
Joined: Tue Aug 19, 2014 10:46 am
x 5

eglSwapBuffers failure when not call windowMovedOrResized

Post by longer »

i logger the v1-9-0 SwapBuffers and the Ogre::Root->renderOneFrame(interval);

Code: Select all

01-06 00:55:41.500: D/DishRendererRunnable(27911): DishRendererRunnable run 0.
01-06 00:55:41.500: I/ogre(27911): 7 I EGLContext::setCurrent
01-06 00:55:42.550: I/ogre(27911): 7 I EGLWindow::swapBuffers
01-06 00:55:42.550: D/DishRendererRunnable(27911): DishRendererRunnable run 1.
anything is work.
but when i use the v1-10-8 not have the setCurrent i think i must missed something.

Code: Select all

01-06 00:55:41.500: I/ogre(27911): 7 I EGLContext::setCurrent
I find that v1-9-0 Samples:

Code: Select all

	JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_renderOneFrame(JNIEnv * env, jobject obj)
	{
		if(gRenderWnd != NULL && gRenderWnd->isActive())
		{
			try
			{
				if(gVM->AttachCurrentThread(&env, NULL) < 0) 					
					return;
				
				gRenderWnd->windowMovedOrResized();
				gRoot->renderOneFrame();
				
				//gVM->DetachCurrentThread();				
			}catch(Ogre::RenderingAPIException ex) {}
		}
	}
v1-10-8 Samples:

Code: Select all

                            if (initOGRE && wndCreate) {
                                ogreApp.getRenderWindow().windowMovedOrResized();
                                ogreApp.getRoot().renderOneFrame();
                            }
have a strange gRenderWnd->windowMovedOrResized();.
at low android version will case a eglSwapBuffers failure when not call windowMovedOrResized.
but here the windowMovedOrResized is puzzling and magic.
version:samsung-gt_s7568-sp-e691e9c1 android 4.0.4.

Code: Select all

	void AndroidEGLWindow::windowMovedOrResized()
	{
        if(mActive)
        {		
			// When using GPU rendering for Android UI the os creates a context in the main thread
			// Now we have 2 choices create OGRE in its own thread or set our context current before doing
			// anything else. I put this code here because this function called before any rendering is done.
			// Because the events for screen rotation / resizing did not worked on all devices it is the best way
			// to query the correct dimensions.
	        mContext->setCurrent(); 
            eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth);
            eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight);
            
            // Notify viewports of resize
            ViewportList::iterator it = mViewportList.begin();
            while( it != mViewportList.end() )
                (*it++).second->_updateDimensions();
        }
	}
mContext->setCurrent(); is here.

i find when the eglSwapBuffers failure the mEglDisplay mDrawable mContext pointer is not change.

Code: Select all

        EGLBoolean ret = eglMakeCurrent(mEglDisplay, mDrawable, mDrawable, mContext);
and it is not always failure,the first few render frame is working and failure at after.What is it happen?.
the better solution is eglMakeCurrent for make sure context correct.

Code: Select all

01-06 04:19:40.350: D/mm_flake_surface_view(2673): surfaceCreated.
01-06 04:19:40.360: D/mm_flake_surface_view(2673): surfaceChanged format:4 480x800
01-06 04:19:40.360: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 0.
01-06 04:19:40.630: I/ogre(2673): 7 I EGLWindow::swapBuffers
01-06 04:19:40.630: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 1.
01-06 04:19:40.630: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 0.
01-06 04:19:40.640: I/ogre(2673): 7 I EGLWindow::swapBuffers
01-06 04:19:40.650: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 1.
01-06 04:19:40.740: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 0.
01-06 04:19:40.750: I/ogre(2673): 7 I EGLWindow::swapBuffers
01-06 04:19:40.760: E/ogre(2673): 1 F RenderingAPIException: Fail to SwapBuffers in swapBuffers at jni/../../../../src/Ogre/RenderSystems/GLSupport/src/EGL/OgreEGLWindow.cpp (line 164)
01-06 04:19:40.760: E/mm(2673): 1 F on_render_one_frame 526 a untreated exception occur:RenderingAPIException: Fail to SwapBuffers in swapBuffers at jni/../../../../src/Ogre/RenderSystems/GLSupport/src/EGL/OgreEGLWindow.cpp (line 164)
01-06 04:19:40.760: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 1.
01-06 04:19:40.760: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 0.
01-06 04:19:40.760: I/ogre(2673): 7 I EGLWindow::swapBuffers
01-06 04:19:40.760: E/ogre(2673): 1 F RenderingAPIException: Fail to SwapBuffers in swapBuffers at jni/../../../../src/Ogre/RenderSystems/GLSupport/src/EGL/OgreEGLWindow.cpp (line 164)
01-06 04:19:40.760: E/mm(2673): 1 F on_render_one_frame 526 a untreated exception occur:RenderingAPIException: Fail to SwapBuffers in swapBuffers at jni/../../../../src/Ogre/RenderSystems/GLSupport/src/EGL/OgreEGLWindow.cpp (line 164)
01-06 04:19:40.760: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 1.
01-06 04:19:40.780: D/OpenGLRenderer(2673): GL error from OpenGLRenderer: 0x501
01-06 04:19:40.790: D/CLIPBOARD(2673): Hide Clipboard dialog at Starting input: finished by someone else... !
01-06 04:19:40.790: D/mm_flake_renderer_loop(2673): DishRendererRunnable run 0.
Can it do eglMakeCurrent at "void GLES2RenderSystem::_setRenderTarget(RenderTarget *target)"?It is working well.not need call windowMovedOrResized.

Code: Select all

    void GLES2RenderSystem::_setRenderTarget(RenderTarget *target)
    {
        // Unbind frame buffer object
        if(mActiveRenderTarget && mRTTManager)
            mRTTManager->unbind(mActiveRenderTarget);

        mActiveRenderTarget = target;
        if (target && mRTTManager)
        {
            // Switch context if different from current one
            GLContext *newContext = 0;
            target->getCustomAttribute("GLCONTEXT", &newContext);
            //if (newContext && mCurrentContext != newContext)
            //{
            //    _switchContext(newContext);
            //}
			if (NULL != newContext)
			{
				// no matter which case we call Context->setCurrent(),_switchContext call this inside.
				if (mCurrentContext != newContext)
				{
					_switchContext(newContext);
				}
				else
				{
					newContext->setCurrent();
				}				
			}

            // Check the FBO's depth buffer status
            GLES2DepthBuffer *depthBuffer = static_cast<GLES2DepthBuffer*>(target->getDepthBuffer());

            if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH &&
                (!depthBuffer || depthBuffer->getGLContext() != mCurrentContext ) )
            {
                // Depth is automatically managed and there is no depth buffer attached to this RT
                // or the Current context doesn't match the one this Depth buffer was created with
                setDepthBufferFor( target );
            }

            // Bind frame buffer object
            mRTTManager->bind(target);
        }
    }
the 2, OgreWin32EGLWindow.cpp windowMovedOrResized is empty for official,i suggest it is can do the same such as dx11.
it is usefull at windows debug gles2 render system and will case bug at cegui when real MovedOrResized:

Code: Select all

    void Win32EGLWindow::windowMovedOrResized()
    {
		if (!mWindow || IsIconic(mWindow))
			return;
		
		RECT rc;
		BOOL result;

		// Update top left parameters
		result = GetWindowRect(mWindow, &rc);
		if (result == FALSE)
		{
			mTop = 0;
			mLeft = 0;
			mWidth = 0;
			mHeight = 0;
			return;
		}

		mTop = rc.top;
		mLeft = rc.left;

		// width and height represent drawable area only
		result = GetClientRect(mWindow, &rc);
		if (result == FALSE)
		{
			mTop = 0;
			mLeft = 0;
			mWidth = 0;
			mHeight = 0;
			return;
		}
		unsigned int width = rc.right - rc.left;
		unsigned int height = rc.bottom - rc.top;

		// Case window resized.
		if (width != mWidth || height != mHeight)
		{
			mWidth  = rc.right - rc.left;
			mHeight = rc.bottom - rc.top;

			// Notify viewports of resize
			ViewportList::iterator it = mViewportList.begin();
			while( it != mViewportList.end() )
				(*it++).second->_updateDimensions();			
		}
    }
Last edited by longer on Tue Oct 31, 2017 9:09 am, edited 1 time in total.
longer
Kobold
Posts: 37
Joined: Tue Aug 19, 2014 10:46 am
x 5

Re: eglSwapBuffers failure when not call windowMovedOrResized

Post by longer »

We can not modify void GLES2RenderSystem::_setRenderTarget(RenderTarget *target).
because some render queue might manual and not trigger GLES2RenderSystem::_setRenderTarget.

finally i add mContext->setCurrent() at RenderTarget::_beginUpdate

Code: Select all

    class _OgrePrivate AndroidEGLWindow : public EGLWindow
...
	public:
		virtual void _beginUpdate();

Code: Select all

	void AndroidEGLWindow::_beginUpdate()
	{
		// at android low version must eglMakeCurrent every frame.
		mContext->setCurrent();
		EGLWindow::_beginUpdate();
	}
is my solution suitable?
paroj
OGRE Team Member
OGRE Team Member
Posts: 1995
Joined: Sun Mar 30, 2014 2:51 pm
x 1075
Contact:

Re: eglSwapBuffers failure when not call windowMovedOrResized

Post by paroj »

this part changed in v1-10-9. Does it improve the situation for you?

I am also afraid I do not fully understand your problem. Do you want to render without calling windowMovedOrResized?

As for the code please create a pull-request for discussion as that way it is easier to see the changes.
longer
Kobold
Posts: 37
Joined: Tue Aug 19, 2014 10:46 am
x 5

Re: eglSwapBuffers failure when not call windowMovedOrResized

Post by longer »

Yes.windowMovedOrResized is puzzling and magic in android rendering loop.
But at android low version(my low machine:samsung-gt_s7568-sp-e691e9c1 android 4.0.4) must be call eglMakeCurrent before any rendering api.

In fact.use this situation all rendering api must after _beginUpdate be call.

so such as cegui rendering must at frameRenderingQueued or frameEnded.

It's work well.

Sorry,i I should learn how to pull-request.Thanks.
Post Reply