OpenGl_Context::MakeCurrent()/OpenGl_Context::IsCurrent() have been modified to NOT fail
in case if myWindow is EGL_NO_SURFACE (valid off-screen rendering case within EGL).
OpenGl_GraphicDriver::InitEglContext() now finds EGL surface config in case if it has not been passed by argument.
OpenGl_Window constructor now allows wrapping an off-screen rendering surface EGL_NO_SURFACE.
However, it still creates a dummy surface eglCreatePbufferSurface() to workaround bugs in some GLES drivers (Vivante GC2000).
V3d_View::SetWindow()/V3d_View::MustBeResized()/V3d_Viewer::SetViewOn() have been modified
to avoid implicit View redraw (leading to undefined behavior/crashes in case if rendering
should be done into default FBO defined right after V3d_View initialization).
{
#if defined(HAVE_EGL)
if ((EGLDisplay )myDisplay == EGL_NO_DISPLAY
- || (EGLSurface )myWindow == EGL_NO_SURFACE
|| (EGLContext )myGContext == EGL_NO_CONTEXT)
{
return Standard_False;
{
#if defined(HAVE_EGL)
if ((EGLDisplay )myDisplay == EGL_NO_DISPLAY
- || (EGLSurface )myWindow == EGL_NO_SURFACE
|| (EGLContext )myGContext == EGL_NO_CONTEXT)
{
Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
namespace
{
static const Handle(OpenGl_Context) TheNullGlCtx;
+
+#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
+ //! Wrapper over eglChooseConfig() called with preferred defaults.
+ static EGLConfig chooseEglSurfConfig (EGLDisplay theDisplay)
+ {
+ EGLint aConfigAttribs[] =
+ {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 24,
+ EGL_STENCIL_SIZE, 8,
+ #if defined(GL_ES_VERSION_2_0)
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ #else
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+ #endif
+ EGL_NONE
+ };
+
+ EGLConfig aCfg = NULL;
+ EGLint aNbConfigs = 0;
+ if (eglChooseConfig (theDisplay, aConfigAttribs, &aCfg, 1, &aNbConfigs) == EGL_TRUE
+ || aCfg != NULL)
+ {
+ return aCfg;
+ }
+
+ eglGetError();
+ aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
+ if (eglChooseConfig (theDisplay, aConfigAttribs, &aCfg, 1, &aNbConfigs) != EGL_TRUE
+ || aCfg == NULL)
+ {
+ eglGetError();
+ }
+ return aCfg;
+ }
+#endif
}
// =======================================================================
return Standard_False;
}
- EGLint aConfigAttribs[] =
- {
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 0,
- EGL_DEPTH_SIZE, 24,
- EGL_STENCIL_SIZE, 8,
- #if defined(GL_ES_VERSION_2_0)
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- #else
- EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
- #endif
- EGL_NONE
- };
-
- EGLint aNbConfigs = 0;
- if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
- || myEglConfig == NULL)
+ myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay);
+ if (myEglConfig == NULL)
{
- eglGetError();
- aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
- if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
- || myEglConfig == NULL)
- {
- ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail);
- return Standard_False;
- }
+ ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail);
+ return Standard_False;
}
#if defined(GL_ES_VERSION_2_0)
#endif
if ((EGLDisplay )theEglDisplay == EGL_NO_DISPLAY
- || (EGLContext )theEglContext == EGL_NO_CONTEXT
- || theEglConfig == NULL)
+ || (EGLContext )theEglContext == EGL_NO_CONTEXT)
{
return Standard_False;
}
myEglDisplay = theEglDisplay;
myEglContext = theEglContext;
myEglConfig = theEglConfig;
+ if (theEglConfig == NULL)
+ {
+ myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay);
+ if (myEglConfig == NULL)
+ {
+ ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail);
+ return Standard_False;
+ }
+ }
return Standard_True;
}
#endif
#include <OpenGl_Context.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OpenGl_Window.hxx>
+#include <OpenGl_FrameBuffer.hxx>
#include <Aspect_GraphicDeviceDefinitionError.hxx>
#include <Graphic3d_TransformUtils.hxx>
EGLConfig anEglConfig = (EGLConfig )theDriver->getRawGlConfig();
if (anEglDisplay == EGL_NO_DISPLAY
|| anEglContext == EGL_NO_CONTEXT
- || anEglConfig == NULL)
+ || (anEglConfig == NULL
+ && (EGLContext )theGContext == EGL_NO_CONTEXT))
{
throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL does not provide compatible configurations!");
return;
}
EGLSurface anEglSurf = EGL_NO_SURFACE;
- if (theGContext == (EGLContext )EGL_NO_CONTEXT)
+ if ((EGLContext )theGContext == EGL_NO_CONTEXT)
{
// create new surface
anEglSurf = eglCreateWindowSurface (anEglDisplay,
anEglSurf = eglGetCurrentSurface(EGL_DRAW);
if (anEglSurf == EGL_NO_SURFACE)
{
- throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to retrieve current surface!");
- return;
+ // window-less EGL context (off-screen)
+ //throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to retrieve current surface!");
+ if (anEglConfig != NULL)
+ {
+ const int aSurfAttribs[] =
+ {
+ EGL_WIDTH, myWidth,
+ EGL_HEIGHT, myHeight,
+ EGL_NONE
+ };
+ anEglSurf = eglCreatePbufferSurface (anEglDisplay, anEglConfig, aSurfAttribs);
+ if (anEglSurf == EGL_NO_SURFACE)
+ {
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to create off-screen surface!");
+ }
+ }
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
+ "OpenGl_Window::CreateWindow: WARNING, a Window is created without a EGL Surface!");
}
}
return;
#if defined(HAVE_EGL)
- if (!myPlatformWindow->IsVirtual())
+ if ((EGLSurface )myGlContext->myWindow == EGL_NO_SURFACE)
+ {
+ // define an offscreen default FBO to avoid rendering into EGL_NO_SURFACE;
+ // note that this code is currently never called, since eglCreatePbufferSurface() is used instead as more robust solution
+ // for offscreen rendering on bugged OpenGL ES drivers
+ Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (Handle(OpenGl_FrameBuffer)());
+ if (!aDefFbo.IsNull())
+ {
+ aDefFbo->Release (myGlContext.operator->());
+ }
+ else
+ {
+ aDefFbo = new OpenGl_FrameBuffer();
+ }
+
+ if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, GL_RGBA8, GL_DEPTH24_STENCIL8))
+ {
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ }
+ myGlContext->SetDefaultFrameBuffer (aDefFbo);
+ aDefFbo->BindBuffer (myGlContext);
+ }
+ else if (!myPlatformWindow->IsVirtual())
{
eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_WIDTH, &myWidth);
eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_HEIGHT, &myHeight);
myView->SetWindow (theWindow, theContext);
MyViewer->SetViewOn (this);
SetRatio();
- Redraw();
+ if (myImmediateUpdate)
+ {
+ Redraw();
+ }
}
//=============================================================================
myView->Resized();
SetRatio();
-
- Redraw();
+ if (myImmediateUpdate)
+ {
+ Redraw();
+ }
}
//=============================================================================
theView->SetGrid (myPrivilegedPlane, Grid ());
theView->SetGridActivity (Grid ()->IsActive ());
- theView->Redraw();
+ if (theView->SetImmediateUpdate (Standard_False))
+ {
+ theView->Redraw();
+ theView->SetImmediateUpdate (Standard_True);
+ }
}
// ========================================================================