egldisplay: Backport changes for creating headless EGL contexts

Backport of fbc49474557fe7b2ec1875ebb1cfb62e96e7f103 and 9f1289b4920074feb7f0b9b203d2a5b6e811c816

See #557
This commit is contained in:
rdb 2020-05-19 22:33:48 +02:00
parent b3f0768656
commit 8924b77da4
14 changed files with 240 additions and 113 deletions

View File

@ -2695,6 +2695,9 @@ def WriteConfigSettings():
dtool_config["PHAVE_LINUX_INPUT_H"] = 'UNDEF' dtool_config["PHAVE_LINUX_INPUT_H"] = 'UNDEF'
dtool_config["IS_OSX"] = '1' dtool_config["IS_OSX"] = '1'
if PkgSkip("X11"):
dtool_config["HAVE_GLX"] = 'UNDEF'
if (GetTarget() == "freebsd"): if (GetTarget() == "freebsd"):
dtool_config["IS_LINUX"] = 'UNDEF' dtool_config["IS_LINUX"] = 'UNDEF'
dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF' dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
@ -5141,13 +5144,33 @@ if (GetTarget() == 'windows' and PkgSkip("GL")==0 and not RUNTIME):
# DIRECTORY: panda/src/egldisplay/ # DIRECTORY: panda/src/egldisplay/
# #
if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0 and not RUNTIME): # If we're not compiling with any windowing system at all, but we do have EGL,
# we can use that to create a headless libpandagl instead.
if not PkgSkip("EGL") and not PkgSkip("GL") and PkgSkip("X11") and GetTarget() not in ('windows', 'darwin') and not RUNTIME:
DefSymbol('EGL', 'HAVE_EGL', '')
OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGL', 'GL', 'EGL']
TargetAdd('pandagl_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
OPTS=['DIR:panda/metalibs/pandagl', 'BUILDING:PANDAGL', 'GL', 'EGL']
TargetAdd('pandagl_pandagl.obj', opts=OPTS, input='pandagl.cxx')
TargetAdd('libpandagl.dll', input='pandagl_pandagl.obj')
TargetAdd('libpandagl.dll', input='p3glgsg_config_glgsg.obj')
TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj')
TargetAdd('libpandagl.dll', input='pandagl_egldisplay_composite1.obj')
TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'EGL', 'CGGL'])
#
# DIRECTORY: panda/src/egldisplay/
#
if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and not RUNTIME):
DefSymbol('GLES', 'OPENGLES_1', '') DefSymbol('GLES', 'OPENGLES_1', '')
OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES', 'GLES', 'EGL'] OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES', 'GLES', 'EGL']
TargetAdd('pandagles_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx') TargetAdd('pandagles_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
OPTS=['DIR:panda/metalibs/pandagles', 'BUILDING:PANDAGLES', 'GLES', 'EGL'] OPTS=['DIR:panda/metalibs/pandagles', 'BUILDING:PANDAGLES', 'GLES', 'EGL']
TargetAdd('pandagles_pandagles.obj', opts=OPTS, input='pandagles.cxx') TargetAdd('pandagles_pandagles.obj', opts=OPTS, input='pandagles.cxx')
TargetAdd('libpandagles.dll', input='p3x11display_composite1.obj') if not PkgSkip("X11"):
TargetAdd('libpandagles.dll', input='p3x11display_composite1.obj')
TargetAdd('libpandagles.dll', input='pandagles_pandagles.obj') TargetAdd('libpandagles.dll', input='pandagles_pandagles.obj')
TargetAdd('libpandagles.dll', input='p3glesgsg_config_glesgsg.obj') TargetAdd('libpandagles.dll', input='p3glesgsg_config_glesgsg.obj')
TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj') TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj')
@ -5159,13 +5182,14 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0 and not RUNTI
# DIRECTORY: panda/src/egldisplay/ # DIRECTORY: panda/src/egldisplay/
# #
if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and PkgSkip("X11")==0 and not RUNTIME): if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and not RUNTIME):
DefSymbol('GLES2', 'OPENGLES_2', '') DefSymbol('GLES2', 'OPENGLES_2', '')
OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL'] OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL']
TargetAdd('pandagles2_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx') TargetAdd('pandagles2_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
OPTS=['DIR:panda/metalibs/pandagles2', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL'] OPTS=['DIR:panda/metalibs/pandagles2', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL']
TargetAdd('pandagles2_pandagles2.obj', opts=OPTS, input='pandagles2.cxx') TargetAdd('pandagles2_pandagles2.obj', opts=OPTS, input='pandagles2.cxx')
TargetAdd('libpandagles2.dll', input='p3x11display_composite1.obj') if not PkgSkip("X11"):
TargetAdd('libpandagles2.dll', input='p3x11display_composite1.obj')
TargetAdd('libpandagles2.dll', input='pandagles2_pandagles2.obj') TargetAdd('libpandagles2.dll', input='pandagles2_pandagles2.obj')
TargetAdd('libpandagles2.dll', input='p3gles2gsg_config_gles2gsg.obj') TargetAdd('libpandagles2.dll', input='p3gles2gsg_config_gles2gsg.obj')
TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj') TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj')

View File

@ -26,8 +26,13 @@
#include "glxGraphicsPipe.h" #include "glxGraphicsPipe.h"
#endif #endif
#if !defined(HAVE_WGL) && !defined(HAVE_COCOA) && !defined(HAVE_CARBON) && !defined(HAVE_GLX) #if defined(HAVE_EGL) && !defined(HAVE_X11)
#error One of HAVE_WGL, HAVE_COCOA, HAVE_CARBON or HAVE_GLX must be defined when compiling pandagl! #include "config_egldisplay.h"
#include "eglGraphicsPipe.h"
#endif
#if !defined(HAVE_WGL) && !defined(HAVE_COCOA) && !defined(HAVE_CARBON) && !defined(HAVE_GLX) && !defined(HAVE_EGL)
#error One of HAVE_WGL, HAVE_COCOA, HAVE_CARBON, HAVE_GLX or HAVE_EGL must be defined when compiling pandagl!
#endif #endif
/** /**
@ -50,9 +55,13 @@ init_libpandagl() {
init_libosxdisplay(); init_libosxdisplay();
#endif #endif
#ifdef IS_LINUX #ifdef HAVE_GLX
init_libglxdisplay(); init_libglxdisplay();
#endif #endif
#if defined(HAVE_EGL) && !defined(HAVE_X11)
init_libegldisplay();
#endif
} }
/** /**
@ -75,5 +84,9 @@ get_pipe_type_pandagl() {
return glxGraphicsPipe::get_class_type().get_index(); return glxGraphicsPipe::get_class_type().get_index();
#endif #endif
#if defined(HAVE_EGL) && !defined(HAVE_X11)
return eglGraphicsPipe::get_class_type().get_index();
#endif
return 0; return 0;
} }

View File

@ -21,8 +21,8 @@
#include "dconfig.h" #include "dconfig.h"
#include "pandaSystem.h" #include "pandaSystem.h"
#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDAGLES) && !defined(BUILDING_PANDAGLES2) #if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDAGLES) && !defined(BUILDING_PANDAGLES2) && !defined(BUILDING_PANDAGL)
#error Buildsystem error: BUILDING_PANDAGLES(2) not defined #error Buildsystem error: BUILDING_PANDAGL(ES(2)) not defined
#endif #endif
Configure(config_egldisplay); Configure(config_egldisplay);
@ -48,8 +48,10 @@ init_libegldisplay() {
eglGraphicsBuffer::init_type(); eglGraphicsBuffer::init_type();
eglGraphicsPipe::init_type(); eglGraphicsPipe::init_type();
#ifdef HAVE_X11
eglGraphicsPixmap::init_type(); eglGraphicsPixmap::init_type();
eglGraphicsWindow::init_type(); eglGraphicsWindow::init_type();
#endif
eglGraphicsStateGuardian::init_type(); eglGraphicsStateGuardian::init_type();
GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
@ -59,8 +61,10 @@ init_libegldisplay() {
PandaSystem *ps = PandaSystem::get_global_ptr(); PandaSystem *ps = PandaSystem::get_global_ptr();
#ifdef OPENGLES_2 #ifdef OPENGLES_2
ps->set_system_tag("OpenGL ES 2", "window_system", "EGL"); ps->set_system_tag("OpenGL ES 2", "window_system", "EGL");
#else #elif defined(OPENGLES_1)
ps->set_system_tag("OpenGL ES", "window_system", "EGL"); ps->set_system_tag("OpenGL ES", "window_system", "EGL");
#else
ps->set_system_tag("OpenGL", "window_system", "EGL");
#endif #endif
} }

View File

@ -23,20 +23,22 @@
#if defined(OPENGLES_1) && defined(OPENGLES_2) #if defined(OPENGLES_1) && defined(OPENGLES_2)
#error OPENGLES_1 and OPENGLES_2 cannot be defined at the same time! #error OPENGLES_1 and OPENGLES_2 cannot be defined at the same time!
#endif #endif
#if !defined(OPENGLES_1) && !defined(OPENGLES_2)
#error Either OPENGLES_1 or OPENGLES_2 must be defined when compiling egldisplay!
#endif
#ifdef OPENGLES_2 #ifdef OPENGLES_2
NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES2, EXPTP_PANDAGLES2); NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES2, EXPTP_PANDAGLES2);
extern EXPCL_PANDAGLES2 void init_libegldisplay(); extern EXPCL_PANDAGLES2 void init_libegldisplay();
extern EXPCL_PANDAGLES2 const std::string get_egl_error_string(int error); extern EXPCL_PANDAGLES2 const std::string get_egl_error_string(int error);
#else #elif defined(OPENGLES_1)
NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES, EXPTP_PANDAGLES); NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES, EXPTP_PANDAGLES);
extern EXPCL_PANDAGLES void init_libegldisplay(); extern EXPCL_PANDAGLES void init_libegldisplay();
extern EXPCL_PANDAGLES const std::string get_egl_error_string(int error); extern EXPCL_PANDAGLES const std::string get_egl_error_string(int error);
#else
NotifyCategoryDecl(egldisplay, EXPCL_PANDAGL, EXPTP_PANDAGL);
extern EXPCL_PANDAGL void init_libegldisplay();
extern EXPCL_PANDAGL const std::string get_egl_error_string(int error);
#endif #endif
#endif #endif

View File

@ -127,7 +127,7 @@ close_buffer() {
if (_gsg != nullptr) { if (_gsg != nullptr) {
eglGraphicsStateGuardian *eglgsg; eglGraphicsStateGuardian *eglgsg;
DCAST_INTO_V(eglgsg, _gsg); DCAST_INTO_V(eglgsg, _gsg);
if (!eglMakeCurrent(eglgsg->_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { if (!eglMakeCurrent(_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
egldisplay_cat.error() << "Failed to call eglMakeCurrent: " egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
<< get_egl_error_string(eglGetError()) << "\n"; << get_egl_error_string(eglGetError()) << "\n";
} }
@ -159,7 +159,7 @@ open_buffer() {
if (_gsg == 0) { if (_gsg == 0) {
// There is no old gsg. Create a new one. // There is no old gsg. Create a new one.
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr); eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false); eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, true, false);
_gsg = eglgsg; _gsg = eglgsg;
} else { } else {
// If the old gsg has the wrong pixel format, create a new one that shares // If the old gsg has the wrong pixel format, create a new one that shares
@ -167,7 +167,7 @@ open_buffer() {
DCAST_INTO_R(eglgsg, _gsg, false); DCAST_INTO_R(eglgsg, _gsg, false);
if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) { if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg); eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false); eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, true, false);
_gsg = eglgsg; _gsg = eglgsg;
} }
} }
@ -178,6 +178,8 @@ open_buffer() {
return false; return false;
} }
_egl_display = eglgsg->_egl_display;
int attrib_list[] = { int attrib_list[] = {
EGL_WIDTH, _size.get_x(), EGL_WIDTH, _size.get_x(),
EGL_HEIGHT, _size.get_y(), EGL_HEIGHT, _size.get_y(),

View File

@ -10,3 +10,11 @@
* @author rdb * @author rdb
* @date 2009-05-21 * @date 2009-05-21
*/ */
/**
*
*/
INLINE EGLDisplay eglGraphicsPipe::
get_egl_display() const {
return _egl_display;
}

View File

@ -25,19 +25,39 @@ TypeHandle eglGraphicsPipe::_type_handle;
* *
*/ */
eglGraphicsPipe:: eglGraphicsPipe::
eglGraphicsPipe(const std::string &display) : x11GraphicsPipe(display) { eglGraphicsPipe() {
//NB. if the X11 display failed to open, _display will be 0, which is a valid
// input to eglGetDisplay - it means to open the default display.
#ifdef HAVE_X11
_egl_display = eglGetDisplay((NativeDisplayType) _display); _egl_display = eglGetDisplay((NativeDisplayType) _display);
#else
_egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
#endif
if (!eglInitialize(_egl_display, nullptr, nullptr)) { if (!eglInitialize(_egl_display, nullptr, nullptr)) {
egldisplay_cat.error() egldisplay_cat.error()
<< "Couldn't initialize the EGL display: " << "Couldn't initialize the EGL display: "
<< get_egl_error_string(eglGetError()) << "\n"; << get_egl_error_string(eglGetError()) << "\n";
_is_valid = false;
return;
} }
#if defined(OPENGLES_1) || defined(OPENGLES_2)
if (!eglBindAPI(EGL_OPENGL_ES_API)) { if (!eglBindAPI(EGL_OPENGL_ES_API)) {
egldisplay_cat.error() egldisplay_cat.error()
<< "Couldn't bind EGL to the OpenGL ES API: " << "Couldn't bind EGL to the OpenGL ES API: "
<< get_egl_error_string(eglGetError()) << "\n"; << get_egl_error_string(eglGetError()) << "\n";
#else
if (!eglBindAPI(EGL_OPENGL_API)) {
egldisplay_cat.error()
<< "Couldn't bind EGL to the OpenGL API: "
<< get_egl_error_string(eglGetError()) << "\n";
#endif
_is_valid = false;
return;
} }
// Even if we don't have an X11 display, we can still render headless.
_is_valid = true;
} }
/** /**
@ -61,7 +81,11 @@ eglGraphicsPipe::
*/ */
std::string eglGraphicsPipe:: std::string eglGraphicsPipe::
get_interface_name() const { get_interface_name() const {
#if defined(OPENGLES_1) || defined(OPENGLES_2)
return "OpenGL ES"; return "OpenGL ES";
#else
return "OpenGL";
#endif
} }
/** /**
@ -110,6 +134,10 @@ make_output(const std::string &name,
// First thing to try: an eglGraphicsWindow // First thing to try: an eglGraphicsWindow
if (retry == 0) { if (retry == 0) {
#ifdef HAVE_X11
if (!_display) {
return nullptr;
}
if (((flags&BF_require_parasite)!=0)|| if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)|| ((flags&BF_refuse_window)!=0)||
((flags&BF_resizeable)!=0)|| ((flags&BF_resizeable)!=0)||
@ -121,9 +149,12 @@ make_output(const std::string &name,
} }
return new eglGraphicsWindow(engine, this, name, fb_prop, win_prop, return new eglGraphicsWindow(engine, this, name, fb_prop, win_prop,
flags, gsg, host); flags, gsg, host);
#else
return nullptr;
#endif
} }
// Second thing to try: a GLES(2)GraphicsBuffer // Second thing to try: a GL(ES(2))GraphicsBuffer
if (retry == 1) { if (retry == 1) {
if ((host==0)|| if ((host==0)||
// (!gl_support_fbo)|| // (!gl_support_fbo)||
@ -154,9 +185,12 @@ make_output(const std::string &name,
#ifdef OPENGLES_2 #ifdef OPENGLES_2
return new GLES2GraphicsBuffer(engine, this, name, fb_prop, win_prop, return new GLES2GraphicsBuffer(engine, this, name, fb_prop, win_prop,
flags, gsg, host); flags, gsg, host);
#else #elif defined(OPENGLES_1)
return new GLESGraphicsBuffer(engine, this, name, fb_prop, win_prop, return new GLESGraphicsBuffer(engine, this, name, fb_prop, win_prop,
flags, gsg, host); flags, gsg, host);
#else
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
flags, gsg, host);
#endif #endif
} }
@ -184,6 +218,10 @@ make_output(const std::string &name,
// Fourth thing to try: an eglGraphicsPixmap. // Fourth thing to try: an eglGraphicsPixmap.
if (retry == 3) { if (retry == 3) {
#ifdef HAVE_X11
if (!_display) {
return nullptr;
}
if (((flags&BF_require_parasite)!=0)|| if (((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)|| ((flags&BF_require_window)!=0)||
((flags&BF_resizeable)!=0)|| ((flags&BF_resizeable)!=0)||
@ -198,6 +236,9 @@ make_output(const std::string &name,
return new eglGraphicsPixmap(engine, this, name, fb_prop, win_prop, return new eglGraphicsPixmap(engine, this, name, fb_prop, win_prop,
flags, gsg, host); flags, gsg, host);
#else
return nullptr;
#endif
} }
// Nothing else left to try. // Nothing else left to try.

View File

@ -15,7 +15,14 @@
#define EGLGRAPHICSPIPE_H #define EGLGRAPHICSPIPE_H
#include "pandabase.h" #include "pandabase.h"
#ifdef HAVE_X11
#include "x11GraphicsPipe.h" #include "x11GraphicsPipe.h"
typedef x11GraphicsPipe BaseGraphicsPipe;
#else
#include "graphicsPipe.h"
typedef GraphicsPipe BaseGraphicsPipe;
#endif
#ifdef OPENGLES_2 #ifdef OPENGLES_2
#include "gles2gsg.h" #include "gles2gsg.h"
@ -25,11 +32,16 @@
#define NativeDisplayType EGLNativeDisplayType #define NativeDisplayType EGLNativeDisplayType
#define NativePixmapType EGLNativePixmapType #define NativePixmapType EGLNativePixmapType
#define NativeWindowType EGLNativeWindowType #define NativeWindowType EGLNativeWindowType
#else #elif defined(OPENGLES_1)
#include "glesgsg.h" #include "glesgsg.h"
#include "pre_x11_include.h" #include "pre_x11_include.h"
#include <GLES/egl.h> #include <GLES/egl.h>
#include "post_x11_include.h" #include "post_x11_include.h"
#else
#include "glgsg.h"
#include "pre_x11_include.h"
#include <EGL/egl.h>
#include "post_x11_include.h"
#endif #endif
class FrameBufferProperties; class FrameBufferProperties;
@ -42,14 +54,16 @@ class eglGraphicsWindow;
* This graphics pipe represents the interface for creating OpenGL ES graphics * This graphics pipe represents the interface for creating OpenGL ES graphics
* windows on an X-based (e.g. Unix) client. * windows on an X-based (e.g. Unix) client.
*/ */
class eglGraphicsPipe : public x11GraphicsPipe { class eglGraphicsPipe : public BaseGraphicsPipe {
public: public:
eglGraphicsPipe(const std::string &display = std::string()); eglGraphicsPipe();
virtual ~eglGraphicsPipe(); virtual ~eglGraphicsPipe();
virtual std::string get_interface_name() const; virtual std::string get_interface_name() const;
static PT(GraphicsPipe) pipe_constructor(); static PT(GraphicsPipe) pipe_constructor();
INLINE EGLDisplay get_egl_display() const;
protected: protected:
virtual PT(GraphicsOutput) make_output(const std::string &name, virtual PT(GraphicsOutput) make_output(const std::string &name,
const FrameBufferProperties &fb_prop, const FrameBufferProperties &fb_prop,
@ -62,16 +76,16 @@ protected:
bool &precertify); bool &precertify);
private: private:
EGLDisplay _egl_display; EGLDisplay _egl_display = 0;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;
} }
static void init_type() { static void init_type() {
x11GraphicsPipe::init_type(); BaseGraphicsPipe::init_type();
register_type(_type_handle, "eglGraphicsPipe", register_type(_type_handle, "eglGraphicsPipe",
x11GraphicsPipe::get_class_type()); BaseGraphicsPipe::get_class_type());
} }
virtual TypeHandle get_type() const { virtual TypeHandle get_type() const {
return get_class_type(); return get_class_type();
@ -80,10 +94,6 @@ public:
private: private:
static TypeHandle _type_handle; static TypeHandle _type_handle;
friend class eglGraphicsBuffer;
friend class eglGraphicsPixmap;
friend class eglGraphicsWindow;
}; };
#include "eglGraphicsPipe.I" #include "eglGraphicsPipe.I"

View File

@ -12,6 +12,9 @@
*/ */
#include "eglGraphicsPixmap.h" #include "eglGraphicsPixmap.h"
#ifdef HAVE_X11
#include "eglGraphicsWindow.h" #include "eglGraphicsWindow.h"
#include "eglGraphicsStateGuardian.h" #include "eglGraphicsStateGuardian.h"
#include "config_egldisplay.h" #include "config_egldisplay.h"
@ -37,8 +40,7 @@ eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
{ {
eglGraphicsPipe *egl_pipe; eglGraphicsPipe *egl_pipe;
DCAST_INTO_V(egl_pipe, _pipe); DCAST_INTO_V(egl_pipe, _pipe);
_display = egl_pipe->get_display(); _egl_display = egl_pipe->get_egl_display();
_egl_display = egl_pipe->_egl_display;
_drawable = None; _drawable = None;
_x_pixmap = None; _x_pixmap = None;
_egl_surface = EGL_NO_SURFACE; _egl_surface = EGL_NO_SURFACE;
@ -167,7 +169,7 @@ open_buffer() {
if (_gsg == 0) { if (_gsg == 0) {
// There is no old gsg. Create a new one. // There is no old gsg. Create a new one.
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr); eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
eglgsg->choose_pixel_format(_fb_properties, _display, egl_pipe->get_screen(), false, true); eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, false, true);
_gsg = eglgsg; _gsg = eglgsg;
} else { } else {
// If the old gsg has the wrong pixel format, create a new one that shares // If the old gsg has the wrong pixel format, create a new one that shares
@ -175,7 +177,7 @@ open_buffer() {
DCAST_INTO_R(eglgsg, _gsg, false); DCAST_INTO_R(eglgsg, _gsg, false);
if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) { if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg); eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
eglgsg->choose_pixel_format(_fb_properties, _display, egl_pipe->get_screen(), false, true); eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, false, true);
_gsg = eglgsg; _gsg = eglgsg;
} }
} }
@ -194,6 +196,7 @@ open_buffer() {
return false; return false;
} }
_display = egl_pipe->get_display();
_drawable = egl_pipe->get_root(); _drawable = egl_pipe->get_root();
if (_host != nullptr) { if (_host != nullptr) {
if (_host->is_of_type(eglGraphicsWindow::get_class_type())) { if (_host->is_of_type(eglGraphicsWindow::get_class_type())) {
@ -241,3 +244,5 @@ open_buffer() {
_is_valid = true; _is_valid = true;
return true; return true;
} }
#endif // HAVE_X11

View File

@ -16,6 +16,8 @@
#include "pandabase.h" #include "pandabase.h"
#ifdef HAVE_X11
#include "eglGraphicsPipe.h" #include "eglGraphicsPipe.h"
#include "graphicsBuffer.h" #include "graphicsBuffer.h"
@ -67,4 +69,6 @@ private:
static TypeHandle _type_handle; static TypeHandle _type_handle;
}; };
#endif // HAVE_X11
#endif #endif

View File

@ -25,19 +25,11 @@ TypeHandle eglGraphicsStateGuardian::_type_handle;
eglGraphicsStateGuardian:: eglGraphicsStateGuardian::
eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
eglGraphicsStateGuardian *share_with) : eglGraphicsStateGuardian *share_with) :
#ifdef OPENGLES_2 BaseGraphicsStateGuardian(engine, pipe)
GLES2GraphicsStateGuardian(engine, pipe)
#else
GLESGraphicsStateGuardian(engine, pipe)
#endif
{ {
_share_context=0; _share_context=0;
_context=0; _context=0;
_display=0;
_egl_display=0; _egl_display=0;
_screen=0;
_visual=0;
_visuals=0;
_fbconfig=0; _fbconfig=0;
if (share_with != nullptr) { if (share_with != nullptr) {
@ -51,9 +43,6 @@ eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
*/ */
eglGraphicsStateGuardian:: eglGraphicsStateGuardian::
~eglGraphicsStateGuardian() { ~eglGraphicsStateGuardian() {
if (_visuals != nullptr) {
XFree(_visuals);
}
if (_context != (EGLContext)nullptr) { if (_context != (EGLContext)nullptr) {
if (!eglDestroyContext(_egl_display, _context)) { if (!eglDestroyContext(_egl_display, _context)) {
egldisplay_cat.error() << "Failed to destroy EGL context: " egldisplay_cat.error() << "Failed to destroy EGL context: "
@ -108,11 +97,6 @@ get_properties(FrameBufferProperties &properties,
slow = true; slow = true;
} }
if ((surface_type & EGL_WINDOW_BIT)==0) {
// We insist on having a context that will support an onscreen window.
return;
}
properties.set_back_buffers(1); properties.set_back_buffers(1);
properties.set_rgb_color(1); properties.set_rgb_color(1);
properties.set_rgba_bits(red_size, green_size, blue_size, alpha_size); properties.set_rgba_bits(red_size, green_size, blue_size, alpha_size);
@ -131,26 +115,23 @@ get_properties(FrameBufferProperties &properties,
*/ */
void eglGraphicsStateGuardian:: void eglGraphicsStateGuardian::
choose_pixel_format(const FrameBufferProperties &properties, choose_pixel_format(const FrameBufferProperties &properties,
X11_Display *display, eglGraphicsPipe *egl_pipe, bool need_window,
int screen, bool need_pbuffer, bool need_pixmap) { bool need_pbuffer, bool need_pixmap) {
_display = display; _egl_display = egl_pipe->get_egl_display();
_egl_display = eglGetDisplay((NativeDisplayType) display);
_screen = screen;
_context = 0; _context = 0;
_fbconfig = 0; _fbconfig = 0;
_visual = 0;
_visuals = 0;
_fbprops.clear(); _fbprops.clear();
int attrib_list[] = { int attrib_list[] = {
#ifdef OPENGLES_1 #if defined(OPENGLES_1)
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif #elif defined(OPENGLES_2)
#ifdef OPENGLES_2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
#endif #endif
EGL_SURFACE_TYPE, EGL_DONT_CARE, EGL_SURFACE_TYPE, need_window ? EGL_WINDOW_BIT : EGL_DONT_CARE,
EGL_NONE EGL_NONE
}; };
@ -206,23 +187,56 @@ choose_pixel_format(const FrameBufferProperties &properties,
best_props = fbprops; best_props = fbprops;
} }
} }
int depth = DefaultDepth(_display, _screen); #ifdef HAVE_X11
_visual = new XVisualInfo; X11_Display *display = egl_pipe->get_display();
XMatchVisualInfo(_display, _screen, depth, TrueColor, _visual); if (display) {
int screen = egl_pipe->get_screen();
int depth = DefaultDepth(display, screen);
_visual = new XVisualInfo;
XMatchVisualInfo(display, screen, depth, TrueColor, _visual);
}
#endif
if (best_quality > 0) { if (best_quality > 0) {
egldisplay_cat.debug() egldisplay_cat.debug()
<< "Chosen config " << best_result << ": " << best_props << "\n"; << "Chosen config " << best_result << ": " << best_props << "\n";
_fbconfig = configs[best_result]; _fbconfig = configs[best_result];
EGLint attribs[32];
int n = 0;
#ifdef OPENGLES_2 #ifdef OPENGLES_2
EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; attribs[n++] = EGL_CONTEXT_CLIENT_VERSION;
_context = eglCreateContext(_egl_display, _fbconfig, _share_context, context_attribs); attribs[n++] = 2;
#else #elif defined(OPENGLES_1)
_context = eglCreateContext(_egl_display, _fbconfig, _share_context, nullptr); #else // Regular OpenGL
if (gl_version.get_num_words() > 0) {
attribs[n++] = EGL_CONTEXT_MAJOR_VERSION;
attribs[n++] = gl_version[0];
if (gl_version.get_num_words() > 1) {
attribs[n++] = EGL_CONTEXT_MINOR_VERSION;
attribs[n++] = gl_version[1];
}
}
if (gl_debug) {
attribs[n++] = EGL_CONTEXT_OPENGL_DEBUG;
attribs[n++] = EGL_TRUE;
}
if (gl_forward_compatible) {
attribs[n++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE;
attribs[n++] = EGL_TRUE;
}
#endif #endif
attribs[n] = EGL_NONE;
_context = eglCreateContext(_egl_display, _fbconfig, _share_context, (n > 0) ? attribs : nullptr);
int err = eglGetError(); int err = eglGetError();
if (_context && err == EGL_SUCCESS) { if (_context && err == EGL_SUCCESS) {
if (_visual) { #ifdef HAVE_X11
if (!display || _visual)
#endif
{
// This is set during window creation, but for now we have to pretend // This is set during window creation, but for now we have to pretend
// that we can honor the request, if we support the extension. // that we can honor the request, if we support the extension.
if (properties.get_srgb_color()) { if (properties.get_srgb_color()) {
@ -248,8 +262,9 @@ choose_pixel_format(const FrameBufferProperties &properties,
<< get_egl_error_string(err) << "\n"; << get_egl_error_string(err) << "\n";
_fbconfig = 0; _fbconfig = 0;
_context = 0; _context = 0;
#ifdef HAVE_X11
_visual = 0; _visual = 0;
_visuals = 0; #endif
} }
egldisplay_cat.error() << egldisplay_cat.error() <<
@ -263,11 +278,7 @@ choose_pixel_format(const FrameBufferProperties &properties,
*/ */
void eglGraphicsStateGuardian:: void eglGraphicsStateGuardian::
reset() { reset() {
#ifdef OPENGLES_2 BaseGraphicsStateGuardian::reset();
GLES2GraphicsStateGuardian::reset();
#else
GLESGraphicsStateGuardian::reset();
#endif
if (_gl_renderer == "Software Rasterizer") { if (_gl_renderer == "Software Rasterizer") {
_fbprops.set_force_software(1); _fbprops.set_force_software(1);
@ -295,13 +306,11 @@ egl_is_at_least_version(int major_version, int minor_version) const {
*/ */
void eglGraphicsStateGuardian:: void eglGraphicsStateGuardian::
gl_flush() const { gl_flush() const {
#ifdef HAVE_X11
// This call requires synchronization with X. // This call requires synchronization with X.
LightReMutexHolder holder(eglGraphicsPipe::_x_mutex); LightReMutexHolder holder(eglGraphicsPipe::_x_mutex);
#ifdef OPENGLES_2
GLES2GraphicsStateGuardian::gl_flush();
#else
GLESGraphicsStateGuardian::gl_flush();
#endif #endif
BaseGraphicsStateGuardian::gl_flush();
} }
/** /**
@ -309,13 +318,11 @@ gl_flush() const {
*/ */
GLenum eglGraphicsStateGuardian:: GLenum eglGraphicsStateGuardian::
gl_get_error() const { gl_get_error() const {
#ifdef HAVE_X11
// This call requires synchronization with X. // This call requires synchronization with X.
LightReMutexHolder holder(eglGraphicsPipe::_x_mutex); LightReMutexHolder holder(eglGraphicsPipe::_x_mutex);
#ifdef OPENGLES_2
return GLES2GraphicsStateGuardian::gl_get_error();
#else
return GLESGraphicsStateGuardian::gl_get_error();
#endif #endif
return BaseGraphicsStateGuardian::gl_get_error();
} }
/** /**
@ -323,11 +330,7 @@ gl_get_error() const {
*/ */
void eglGraphicsStateGuardian:: void eglGraphicsStateGuardian::
query_gl_version() { query_gl_version() {
#ifdef OPENGLES_2 BaseGraphicsStateGuardian::query_gl_version();
GLES2GraphicsStateGuardian::query_gl_version();
#else
GLESGraphicsStateGuardian::query_gl_version();
#endif
// Calling eglInitialize on an already-initialized display will just provide // Calling eglInitialize on an already-initialized display will just provide
// us the version numbers. // us the version numbers.
@ -342,9 +345,12 @@ query_gl_version() {
#ifdef OPENGLES_2 #ifdef OPENGLES_2
if (gles2gsg_cat.is_debug()) { if (gles2gsg_cat.is_debug()) {
gles2gsg_cat.debug() gles2gsg_cat.debug()
#else #elif defined(OPENGLES_1)
if (glesgsg_cat.is_debug()) { if (glesgsg_cat.is_debug()) {
glesgsg_cat.debug() glesgsg_cat.debug()
#else
if (glgsg_cat.is_debug()) {
glgsg_cat.debug()
#endif #endif
<< "EGL_VERSION = " << _egl_version_major << "." << _egl_version_minor << "EGL_VERSION = " << _egl_version_major << "." << _egl_version_minor
<< "\n"; << "\n";

View File

@ -16,26 +16,32 @@
#include "pandabase.h" #include "pandabase.h"
#include "eglGraphicsPipe.h" #include "eglGraphicsPipe.h"
#ifdef HAVE_X11
#include "get_x11.h" #include "get_x11.h"
#endif
#ifdef OPENGLES_2
typedef GLES2GraphicsStateGuardian BaseGraphicsStateGuardian;
#elif defined(OPENGLES_1)
typedef GLESGraphicsStateGuardian BaseGraphicsStateGuardian;
#else
typedef GLGraphicsStateGuardian BaseGraphicsStateGuardian;
#endif
/** /**
* A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific * A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific
* information. * information.
*/ */
#ifdef OPENGLES_2 class eglGraphicsStateGuardian : public BaseGraphicsStateGuardian {
class eglGraphicsStateGuardian : public GLES2GraphicsStateGuardian {
#else
class eglGraphicsStateGuardian : public GLESGraphicsStateGuardian {
#endif
public: public:
INLINE const FrameBufferProperties &get_fb_properties() const; INLINE const FrameBufferProperties &get_fb_properties() const;
void get_properties(FrameBufferProperties &properties, void get_properties(FrameBufferProperties &properties,
bool &pbuffer_supported, bool &pixmap_supported, bool &pbuffer_supported, bool &pixmap_supported,
bool &slow, EGLConfig config); bool &slow, EGLConfig config);
void choose_pixel_format(const FrameBufferProperties &properties, void choose_pixel_format(const FrameBufferProperties &properties,
X11_Display *_display, eglGraphicsPipe *egl_pipe, bool need_window,
int _screen, bool need_pbuffer, bool need_pixmap);
bool need_pbuffer, bool need_pixmap);
eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
eglGraphicsStateGuardian *share_with); eglGraphicsStateGuardian *share_with);
@ -49,10 +55,9 @@ public:
EGLContext _share_context; EGLContext _share_context;
EGLContext _context; EGLContext _context;
EGLDisplay _egl_display; EGLDisplay _egl_display;
X11_Display *_display; #ifdef HAVE_X11
int _screen; XVisualInfo *_visual = nullptr;
XVisualInfo *_visual; #endif
XVisualInfo *_visuals;
EGLConfig _fbconfig; EGLConfig _fbconfig;
FrameBufferProperties _fbprops; FrameBufferProperties _fbprops;
@ -72,15 +77,9 @@ public:
return _type_handle; return _type_handle;
} }
static void init_type() { static void init_type() {
#ifdef OPENGLES_2 BaseGraphicsStateGuardian::init_type();
GLES2GraphicsStateGuardian::init_type();
register_type(_type_handle, "eglGraphicsStateGuardian", register_type(_type_handle, "eglGraphicsStateGuardian",
GLES2GraphicsStateGuardian::get_class_type()); BaseGraphicsStateGuardian::get_class_type());
#else
GLESGraphicsStateGuardian::init_type();
register_type(_type_handle, "eglGraphicsStateGuardian",
GLESGraphicsStateGuardian::get_class_type());
#endif
} }
virtual TypeHandle get_type() const { virtual TypeHandle get_type() const {
return get_class_type(); return get_class_type();

View File

@ -12,6 +12,9 @@
*/ */
#include "eglGraphicsWindow.h" #include "eglGraphicsWindow.h"
#ifdef HAVE_X11
#include "eglGraphicsStateGuardian.h" #include "eglGraphicsStateGuardian.h"
#include "config_egldisplay.h" #include "config_egldisplay.h"
#include "eglGraphicsPipe.h" #include "eglGraphicsPipe.h"
@ -52,7 +55,7 @@ eglGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
{ {
eglGraphicsPipe *egl_pipe; eglGraphicsPipe *egl_pipe;
DCAST_INTO_V(egl_pipe, _pipe); DCAST_INTO_V(egl_pipe, _pipe);
_egl_display = egl_pipe->_egl_display; _egl_display = egl_pipe->get_egl_display();
_egl_surface = 0; _egl_surface = 0;
} }
@ -214,7 +217,7 @@ open_window() {
if (_gsg == 0) { if (_gsg == 0) {
// There is no old gsg. Create a new one. // There is no old gsg. Create a new one.
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr); eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), false, false); eglgsg->choose_pixel_format(_fb_properties, egl_pipe, true, false, false);
_gsg = eglgsg; _gsg = eglgsg;
} else { } else {
// If the old gsg has the wrong pixel format, create a new one that shares // If the old gsg has the wrong pixel format, create a new one that shares
@ -222,7 +225,7 @@ open_window() {
DCAST_INTO_R(eglgsg, _gsg, false); DCAST_INTO_R(eglgsg, _gsg, false);
if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) { if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg); eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), false, false); eglgsg->choose_pixel_format(_fb_properties, egl_pipe, true, false, false);
_gsg = eglgsg; _gsg = eglgsg;
} }
} }
@ -275,3 +278,5 @@ open_window() {
return true; return true;
} }
#endif // HAVE_X11

View File

@ -16,6 +16,8 @@
#include "pandabase.h" #include "pandabase.h"
#ifdef HAVE_X11
#include "eglGraphicsPipe.h" #include "eglGraphicsPipe.h"
#include "x11GraphicsWindow.h" #include "x11GraphicsWindow.h"
@ -65,4 +67,6 @@ private:
#include "eglGraphicsWindow.I" #include "eglGraphicsWindow.I"
#endif // HAVE_X11
#endif #endif