20TypeHandle eglGraphicsStateGuardian::_type_handle;
25eglGraphicsStateGuardian::
28 BaseGraphicsStateGuardian(engine, pipe)
35 if (share_with !=
nullptr) {
36 _prepared_objects = share_with->get_prepared_objects();
37 _share_context = share_with->_context;
44eglGraphicsStateGuardian::
45~eglGraphicsStateGuardian() {
46 if (_context != (EGLContext)
nullptr) {
47 if (!eglDestroyContext(_egl_display, _context)) {
48 egldisplay_cat.error() <<
"Failed to destroy EGL context: "
51 _context = (EGLContext)
nullptr;
60 bool &pbuffer_supported,
bool &pixmap_supported,
61 bool &slow, EGLConfig config) {
66 EGLint red_size, green_size, blue_size,
68 depth_size, stencil_size, samples, surface_type, caveat;
70 eglGetConfigAttrib(_egl_display, config, EGL_RED_SIZE, &red_size);
71 eglGetConfigAttrib(_egl_display, config, EGL_GREEN_SIZE, &green_size);
72 eglGetConfigAttrib(_egl_display, config, EGL_BLUE_SIZE, &blue_size);
73 eglGetConfigAttrib(_egl_display, config, EGL_ALPHA_SIZE, &alpha_size);
74 eglGetConfigAttrib(_egl_display, config, EGL_DEPTH_SIZE, &depth_size);
75 eglGetConfigAttrib(_egl_display, config, EGL_STENCIL_SIZE, &stencil_size);
76 eglGetConfigAttrib(_egl_display, config, EGL_SAMPLES, &samples);
77 eglGetConfigAttrib(_egl_display, config, EGL_SURFACE_TYPE, &surface_type);
78 eglGetConfigAttrib(_egl_display, config, EGL_CONFIG_CAVEAT, &caveat);
79 int err = eglGetError();
80 if (err != EGL_SUCCESS) {
81 egldisplay_cat.error() <<
"Failed to get EGL config attrib: "
85 pbuffer_supported =
false;
86 if ((surface_type & EGL_PBUFFER_BIT)!=0) {
87 pbuffer_supported =
true;
90 pixmap_supported =
false;
91 if ((surface_type & EGL_PIXMAP_BIT)!=0) {
92 pixmap_supported =
true;
96 if (caveat == EGL_SLOW_CONFIG) {
100 properties.set_back_buffers(1);
101 properties.set_rgb_color(1);
102 properties.
set_rgba_bits(red_size, green_size, blue_size, alpha_size);
103 properties.set_stencil_bits(stencil_size);
104 properties.set_depth_bits(depth_size);
105 properties.set_multisamples(samples);
108 properties.set_force_software(slow);
109 properties.set_force_hardware(!slow);
119 bool need_pbuffer,
bool need_pixmap) {
121 _egl_display = egl_pipe->get_egl_display();
126 int attrib_list[] = {
127#if defined(OPENGLES_1)
128 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
129#elif defined(OPENGLES_2)
130 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
132 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
134 EGL_SURFACE_TYPE, need_window ? EGL_WINDOW_BIT : EGL_DONT_CARE,
140 int num_configs = 0, returned_configs;
141 if (!eglChooseConfig(_egl_display, attrib_list,
nullptr, num_configs, &returned_configs) || returned_configs <= 0) {
142 egldisplay_cat.error() <<
"eglChooseConfig failed: "
147 num_configs = returned_configs;
148 EGLConfig *configs =
new EGLConfig[num_configs];
150 if (!eglChooseConfig(_egl_display, attrib_list, configs, num_configs, &returned_configs) || returned_configs <= 0) {
151 egldisplay_cat.error() <<
"eglChooseConfig failed: "
157 int best_quality = 0;
161 for (
int i = 0; i < num_configs; ++i) {
163 bool pbuffer_supported, pixmap_supported, slow;
169 const char *pbuffertext = pbuffer_supported ?
" (pbuffer)" :
"";
170 const char *pixmaptext = pixmap_supported ?
" (pixmap)" :
"";
171 const char *slowtext = slow ?
" (slow)" :
"";
172 egldisplay_cat.debug()
173 << i <<
": " << fbprops << pbuffertext << pixmaptext << slowtext <<
"\n";
175 if ((quality > 0)&&(slow)) quality -= 10000000;
177 if (need_pbuffer && !pbuffer_supported) {
180 if (need_pixmap && !pixmap_supported) {
184 if (quality > best_quality) {
185 best_quality = quality;
187 best_props = fbprops;
191 X11_Display *display = egl_pipe->get_display();
193 int screen = egl_pipe->get_screen();
194 int depth = DefaultDepth(display, screen);
195 _visual =
new XVisualInfo;
196 XMatchVisualInfo(display, screen, depth, TrueColor, _visual);
200 if (best_quality > 0) {
201 egldisplay_cat.debug()
202 <<
"Chosen config " << best_result <<
": " << best_props <<
"\n";
203 _fbconfig = configs[best_result];
209 attribs[n++] = EGL_CONTEXT_CLIENT_VERSION;
211#elif defined(OPENGLES_1)
213 if (gl_version.get_num_words() > 0) {
214 attribs[n++] = EGL_CONTEXT_MAJOR_VERSION;
215 attribs[n++] = gl_version[0];
216 if (gl_version.get_num_words() > 1) {
217 attribs[n++] = EGL_CONTEXT_MINOR_VERSION;
218 attribs[n++] = gl_version[1];
222 attribs[n++] = EGL_CONTEXT_OPENGL_DEBUG;
223 attribs[n++] = EGL_TRUE;
225 if (gl_forward_compatible) {
226 attribs[n++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE;
227 attribs[n++] = EGL_TRUE;
230 attribs[n] = EGL_NONE;
232 _context = eglCreateContext(_egl_display, _fbconfig, _share_context, (n > 0) ? attribs :
nullptr);
234 int err = eglGetError();
235 if (_context && err == EGL_SUCCESS) {
237 if (!display || _visual)
242 if (properties.get_srgb_color()) {
243 const char *extensions = eglQueryString(_egl_display, EGL_EXTENSIONS);
244 if (extensions !=
nullptr) {
245 vector_string tokens;
248 if (std::find(tokens.begin(), tokens.end(),
"EGL_KHR_gl_colorspace") != tokens.end()) {
249 best_props.set_srgb_color(
true);
254 _fbprops = best_props;
260 egldisplay_cat.error()
261 <<
"Could not create EGL context!\n"
270 egldisplay_cat.error() <<
271 "Could not find a usable pixel format.\n";
281 BaseGraphicsStateGuardian::reset();
283 if (_gl_renderer ==
"Software Rasterizer") {
284 _fbprops.set_force_software(1);
285 _fbprops.set_force_hardware(0);
295 if (_egl_version_major < major_version) {
298 if (_egl_version_minor < minor_version) {
307void eglGraphicsStateGuardian::
313 BaseGraphicsStateGuardian::gl_flush();
319GLenum eglGraphicsStateGuardian::
320gl_get_error()
const {
325 return BaseGraphicsStateGuardian::gl_get_error();
331void eglGraphicsStateGuardian::
333 BaseGraphicsStateGuardian::query_gl_version();
337 if (!eglInitialize(_egl_display, &_egl_version_major, &_egl_version_minor)) {
338 egldisplay_cat.error() <<
"Failed to get EGL version number: "
346 if (gles2gsg_cat.is_debug()) {
348#elif defined(OPENGLES_1)
349 if (glesgsg_cat.is_debug()) {
352 if (glgsg_cat.is_debug()) {
355 <<
"EGL_VERSION = " << _egl_version_major <<
"." << _egl_version_minor
365void eglGraphicsStateGuardian::
366get_extra_extensions() {
367 save_extensions(eglQueryString(_egl_display, EGL_EXTENSIONS));
376void *eglGraphicsStateGuardian::
377do_get_extension_func(
const char *name) {
378 return (
void *)eglGetProcAddress(name);
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
void set_rgba_bits(int r, int g, int b, int a)
Convenience method for setting the red, green, blue and alpha bits in one go.
void clear()
Unsets all properties that have been specified so far, and resets the FrameBufferProperties structure...
int get_quality(const FrameBufferProperties &reqs) const
Assumes that these properties are a description of a window.
This class is the main interface to controlling the render process.
An object to create GraphicsOutputs that share a particular 3-D API.
Similar to MutexHolder, but for a light reentrant mutex.
TypeHandle is the identifier used to differentiate C++ class types.
This graphics pipe represents the interface for creating OpenGL ES graphics windows on an X-based (e....
A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific information.
virtual void reset()
Resets all internal state as if the gsg were newly created.
bool egl_is_at_least_version(int major_version, int minor_version) const
Returns true if the runtime GLX version number is at least the indicated value, false otherwise.
void choose_pixel_format(const FrameBufferProperties &properties, eglGraphicsPipe *egl_pipe, bool need_window, bool need_pbuffer, bool need_pixmap)
Selects a visual or fbconfig for all the windows and buffers that use this gsg.
void get_properties(FrameBufferProperties &properties, bool &pbuffer_supported, bool &pixmap_supported, bool &slow, EGLConfig config)
Gets the FrameBufferProperties to match the indicated config.
const std::string get_egl_error_string(int error)
Returns the given EGL error as string.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int extract_words(const string &str, vector_string &words)
Divides the string into a number of words according to whitespace.