15 #include "eglGraphicsBuffer.h" 16 #include "eglGraphicsPipe.h" 17 #include "eglGraphicsPixmap.h" 18 #include "eglGraphicsWindow.h" 19 #include "eglGraphicsStateGuardian.h" 20 #include "config_egldisplay.h" 21 #include "frameBufferProperties.h" 25 bool eglGraphicsPipe::_error_handlers_installed =
false;
26 eglGraphicsPipe::ErrorHandlerFunc *eglGraphicsPipe::_prev_error_handler;
27 eglGraphicsPipe::IOErrorHandlerFunc *eglGraphicsPipe::_prev_io_error_handler;
37 eglGraphicsPipe(
const string &display) {
38 string display_spec = display;
39 if (display_spec.empty()) {
40 display_spec = display_cfg;
42 if (display_spec.empty()) {
45 if (display_spec.empty()) {
46 display_spec =
":0.0";
51 setlocale(LC_ALL,
"");
56 setlocale(LC_NUMERIC,
"C");
59 _supported_types = OT_window | OT_buffer | OT_texture_buffer;
62 _root = (X11_Window)NULL;
64 _hidden_cursor = None;
67 install_error_handlers();
69 _display = XOpenDisplay(display_spec.c_str());
71 egldisplay_cat.error()
72 <<
"Could not open display \"" << display_spec <<
"\".\n";
76 if (!XSupportsLocale()) {
77 egldisplay_cat.warning()
78 <<
"X does not support locale " << setlocale(LC_ALL, NULL) <<
"\n";
80 XSetLocaleModifiers(
"");
82 _screen = DefaultScreen(_display);
83 _root = RootWindow(_display, _screen);
84 _display_width = DisplayWidth(_display, _screen);
85 _display_height = DisplayHeight(_display, _screen);
88 _egl_display = eglGetDisplay((NativeDisplayType) _display);
89 if (!eglInitialize(_egl_display, NULL, NULL)) {
90 egldisplay_cat.error()
91 <<
"Couldn't initialize the EGL display: " 92 << get_egl_error_string(eglGetError()) <<
"\n";
95 if (!eglBindAPI(EGL_OPENGL_ES_API)) {
96 egldisplay_cat.error()
97 <<
"Couldn't bind EGL to the OpenGL ES API: " 98 << get_egl_error_string(eglGetError()) <<
"\n";
103 _im = XOpenIM(_display, NULL, NULL, NULL);
104 if (_im == (XIM)NULL) {
105 egldisplay_cat.warning()
106 <<
"Couldn't open input method.\n";
123 _wm_delete_window = XInternAtom(_display,
"WM_DELETE_WINDOW",
false);
124 _net_wm_window_type = XInternAtom(_display,
"_NET_WM_WINDOW_TYPE",
false);
125 _net_wm_window_type_splash = XInternAtom(_display,
"_NET_WM_WINDOW_TYPE_SPLASH",
false);
126 _net_wm_window_type_fullscreen = XInternAtom(_display,
"_NET_WM_WINDOW_TYPE_FULLSCREEN",
false);
127 _net_wm_state = XInternAtom(_display,
"_NET_WM_STATE",
false);
128 _net_wm_state_fullscreen = XInternAtom(_display,
"_NET_WM_STATE_FULLSCREEN",
false);
129 _net_wm_state_above = XInternAtom(_display,
"_NET_WM_STATE_ABOVE",
false);
130 _net_wm_state_below = XInternAtom(_display,
"_NET_WM_STATE_BELOW",
false);
131 _net_wm_state_add = XInternAtom(_display,
"_NET_WM_STATE_ADD",
false);
132 _net_wm_state_remove = XInternAtom(_display,
"_NET_WM_STATE_REMOVE",
false);
142 release_hidden_cursor();
147 XCloseDisplay(_display);
150 if (!eglTerminate(_egl_display)) {
151 egldisplay_cat.error() <<
"Failed to terminate EGL display: " 152 << get_egl_error_string(eglGetError()) <<
"\n";
192 GraphicsPipe::PreferredWindowThread
214 make_output(
const string &name,
230 DCAST_INTO_R(eglgsg, gsg, NULL);
247 if (((flags&BF_require_parasite)!=0)||
248 ((flags&BF_refuse_window)!=0)||
249 ((flags&BF_resizeable)!=0)||
250 ((flags&BF_size_track_host)!=0)||
251 ((flags&BF_rtt_cumulative)!=0)||
252 ((flags&BF_can_bind_color)!=0)||
253 ((flags&BF_can_bind_every)!=0)) {
264 ((flags&BF_require_parasite)!=0)||
265 ((flags&BF_require_window)!=0)) {
270 if ((flags & BF_fb_props_optional)==0) {
271 if ((fb_prop.get_indexed_color() > 0)||
272 (fb_prop.get_back_buffers() > 0)||
273 (fb_prop.get_accum_bits() > 0)||
274 (fb_prop.get_multisamples() > 0)) {
281 (eglgsg->is_valid()) &&
282 (!eglgsg->needs_reset()) &&
283 (eglgsg->_supports_framebuffer_object) &&
284 (eglgsg->_glDrawBuffers != 0)&&
289 return new GLES2GraphicsBuffer(engine,
this, name, fb_prop, win_prop,
292 return new GLESGraphicsBuffer(engine,
this, name, fb_prop, win_prop,
299 if (((flags&BF_require_parasite)!=0)||
300 ((flags&BF_require_window)!=0)||
301 ((flags&BF_resizeable)!=0)||
302 ((flags&BF_size_track_host)!=0)) {
307 if (((flags&BF_rtt_cumulative)!=0)||
308 ((flags&BF_can_bind_every)!=0)) {
321 if (((flags&BF_require_parasite)!=0)||
322 ((flags&BF_require_window)!=0)||
323 ((flags&BF_resizeable)!=0)||
324 ((flags&BF_size_track_host)!=0)) {
328 if (((flags&BF_rtt_cumulative)!=0)||
329 ((flags&BF_can_bind_every)!=0)) {
347 void eglGraphicsPipe::
348 make_hidden_cursor() {
349 nassertv(_hidden_cursor == None);
351 unsigned int x_size, y_size;
352 XQueryBestCursor(_display, _root, 1, 1, &x_size, &y_size);
354 Pixmap empty = XCreatePixmap(_display, _root, x_size, y_size, 1);
357 memset(&black, 0,
sizeof(black));
359 _hidden_cursor = XCreatePixmapCursor(_display, empty, empty,
360 &black, &black, x_size, y_size);
361 XFreePixmap(_display, empty);
370 void eglGraphicsPipe::
371 release_hidden_cursor() {
372 if (_hidden_cursor != None) {
373 XFreeCursor(_display, _hidden_cursor);
374 _hidden_cursor = None;
389 void eglGraphicsPipe::
390 install_error_handlers() {
391 if (_error_handlers_installed) {
395 _prev_error_handler = (ErrorHandlerFunc *)XSetErrorHandler(error_handler);
396 _prev_io_error_handler = (IOErrorHandlerFunc *)XSetIOErrorHandler(io_error_handler);
397 _error_handlers_installed =
true;
406 int eglGraphicsPipe::
407 error_handler(X11_Display *display, XErrorEvent *error) {
408 static const int msg_len = 80;
410 XGetErrorText(display, error->error_code, msg, msg_len);
411 egldisplay_cat.error()
429 int eglGraphicsPipe::
430 io_error_handler(X11_Display *display) {
431 egldisplay_cat.fatal()
432 <<
"X fatal error on display " << (
void *)display <<
"\n";
bool is_basic() const
Returns true if the properties are extremely basic.
A lightweight reentrant mutex.
An interface to the egl system for managing GLES windows under X.
This graphics pipe represents the interface for creating OpenGL ES graphics windows on an X-based (e...
A container for the various kinds of properties we might ask to have on a graphics window before we o...
virtual PreferredWindowThread get_preferred_window_thread() const
Returns an indication of the thread in which this GraphicsPipe requires its window processing to be p...
virtual string get_interface_name() const
Returns the name of the rendering interface associated with this GraphicsPipe.
An object to create GraphicsOutputs that share a particular 3-D API.
Another offscreen buffer in the EGL environment.
static string get_environment_variable(const string &var)
Returns the definition of the indicated environment variable, or the empty string if the variable is ...
This is a base class for the various different classes that represent the result of a frame of render...
An offscreen buffer in the EGL environment.
Encapsulates all the communication with a particular instance of a given rendering backend...
A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific information.
This class is the main interface to controlling the render process.
TypeHandle is the identifier used to differentiate C++ class types.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...