Panda3D
glxGraphicsPipe.cxx
1 // Filename: glxGraphicsPipe.cxx
2 // Created by: mike (09Jan97)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "glxGraphicsPipe.h"
16 #include "glxGraphicsWindow.h"
17 #include "glxGraphicsBuffer.h"
18 #include "glxGraphicsPixmap.h"
19 #include "glxGraphicsStateGuardian.h"
20 #include "posixGraphicsStateGuardian.h"
21 #include "config_glxdisplay.h"
22 #include "frameBufferProperties.h"
23 
24 TypeHandle glxGraphicsPipe::_type_handle;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: glxGraphicsPipe::Constructor
28 // Access: Public
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 glxGraphicsPipe::
32 glxGraphicsPipe(const string &display) : x11GraphicsPipe(display) {
33  if (_display == None) {
34  // Some error must have occurred.
35  return;
36  }
37 
38  string display_spec (XDisplayString(_display));
39 
40  int errorBase, eventBase;
41  if (!glXQueryExtension(_display, &errorBase, &eventBase)) {
42  glxdisplay_cat.error()
43  << "OpenGL GLX extension not supported on display \"" << display_spec
44  << "\".\n";
45  return;
46  }
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: glxGraphicsPipe::get_interface_name
51 // Access: Published, Virtual
52 // Description: Returns the name of the rendering interface
53 // associated with this GraphicsPipe. This is used to
54 // present to the user to allow him/her to choose
55 // between several possible GraphicsPipes available on a
56 // particular platform, so the name should be meaningful
57 // and unique for a given platform.
58 ////////////////////////////////////////////////////////////////////
59 string glxGraphicsPipe::
61  return "OpenGL";
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: glxGraphicsPipe::pipe_constructor
66 // Access: Public, Static
67 // Description: This function is passed to the GraphicsPipeSelection
68 // object to allow the user to make a default
69 // glxGraphicsPipe.
70 ////////////////////////////////////////////////////////////////////
71 PT(GraphicsPipe) glxGraphicsPipe::
72 pipe_constructor() {
73  return new glxGraphicsPipe;
74 }
75 
76 ////////////////////////////////////////////////////////////////////
77 // Function: glxGraphicsPipe::make_output
78 // Access: Protected, Virtual
79 // Description: Creates a new window on the pipe, if possible.
80 ////////////////////////////////////////////////////////////////////
81 PT(GraphicsOutput) glxGraphicsPipe::
82 make_output(const string &name,
83  const FrameBufferProperties &fb_prop,
84  const WindowProperties &win_prop,
85  int flags,
86  GraphicsEngine *engine,
88  GraphicsOutput *host,
89  int retry,
90  bool &precertify) {
91 
92  if (!_is_valid) {
93  return NULL;
94  }
95 
96  // This may not be a GLX GSG; it might be a callback GSG.
97  PosixGraphicsStateGuardian *posixgsg = NULL;
98  glxGraphicsStateGuardian *glxgsg = NULL;
99  if (gsg != NULL) {
100  DCAST_INTO_R(posixgsg, gsg, NULL);
101  glxgsg = DCAST(glxGraphicsStateGuardian, posixgsg);
102  }
103 
104  bool support_rtt;
105  support_rtt = false;
106  /*
107  Currently, no support for glxGraphicsBuffer render-to-texture.
108  if (glxgsg) {
109  support_rtt =
110  glxgsg -> get_supports_render_texture() &&
111  support_render_texture;
112  }
113  */
114 
115  // First thing to try: a glxGraphicsWindow
116 
117  if (retry == 0) {
118  if (gsg != NULL && glxgsg == NULL) {
119  // We can't use a non-GLX GSG.
120  return NULL;
121  }
122  if (((flags&BF_require_parasite)!=0)||
123  ((flags&BF_refuse_window)!=0)||
124  ((flags&BF_resizeable)!=0)||
125  ((flags&BF_size_track_host)!=0)||
126  ((flags&BF_rtt_cumulative)!=0)||
127  ((flags&BF_can_bind_color)!=0)||
128  ((flags&BF_can_bind_every)!=0)||
129  ((flags&BF_can_bind_layered)!=0)) {
130  return NULL;
131  }
132  return new glxGraphicsWindow(engine, this, name, fb_prop, win_prop,
133  flags, gsg, host);
134  }
135 
136  // Second thing to try: a GLGraphicsBuffer
137 
138  if (retry == 1) {
139  if (!gl_support_fbo || host == NULL ||
140  (flags & (BF_require_parasite | BF_require_window)) != 0) {
141  return NULL;
142  }
143  // Early failure - if we are sure that this buffer WONT
144  // meet specs, we can bail out early.
145  if ((flags & BF_fb_props_optional) == 0) {
146  if (fb_prop.get_indexed_color() ||
147  fb_prop.get_back_buffers() > 0 ||
148  fb_prop.get_accum_bits() > 0) {
149  return NULL;
150  }
151  }
152  if (posixgsg != NULL && posixgsg->is_valid() && !posixgsg->needs_reset()) {
153  if (!posixgsg->_supports_framebuffer_object ||
154  posixgsg->_glDrawBuffers == NULL) {
155  return NULL;
156  } else {
157  // Early success - if we are sure that this buffer WILL
158  // meet specs, we can precertify it.
159  precertify = true;
160  }
161  }
162  return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
163  flags, gsg, host);
164  }
165 
166  // Third thing to try: a glxGraphicsBuffer
167  if (glxgsg == NULL || glxgsg->_supports_fbconfig) {
168  if (retry == 2) {
169  if (!glx_support_pbuffer) {
170  return NULL;
171  }
172 
173  if (((flags&BF_require_parasite)!=0)||
174  ((flags&BF_require_window)!=0)||
175  ((flags&BF_resizeable)!=0)||
176  ((flags&BF_size_track_host)!=0)||
177  ((flags&BF_can_bind_layered)!=0)) {
178  return NULL;
179  }
180 
181  if (!support_rtt) {
182  if (((flags&BF_rtt_cumulative)!=0)||
183  ((flags&BF_can_bind_every)!=0)) {
184  // If we require Render-to-Texture, but can't be sure we
185  // support it, bail.
186  return NULL;
187  }
188  }
189 
190  return new glxGraphicsBuffer(engine, this, name, fb_prop, win_prop,
191  flags, gsg, host);
192  }
193  }
194 
195  // Third thing to try: a glxGraphicsPixmap.
196  if (retry == 3) {
197  if (!glx_support_pixmap) {
198  return NULL;
199  }
200 
201  if (((flags&BF_require_parasite)!=0)||
202  ((flags&BF_require_window)!=0)||
203  ((flags&BF_resizeable)!=0)||
204  ((flags&BF_size_track_host)!=0)||
205  ((flags&BF_can_bind_layered)!=0)) {
206  return NULL;
207  }
208 
209  if (((flags&BF_rtt_cumulative)!=0)||
210  ((flags&BF_can_bind_every)!=0)) {
211  return NULL;
212  }
213 
214  return new glxGraphicsPixmap(engine, this, name, fb_prop, win_prop,
215  flags, gsg, host);
216  }
217 
218  // Nothing else left to try.
219  return NULL;
220 }
221 
222 ////////////////////////////////////////////////////////////////////
223 // Function: glxGraphicsPipe::make_callback_gsg
224 // Access: Protected, Virtual
225 // Description: This is called when make_output() is used to create a
226 // CallbackGraphicsWindow. If the GraphicsPipe can
227 // construct a GSG that's not associated with any
228 // particular window object, do so now, assuming the
229 // correct graphics context has been set up externally.
230 ////////////////////////////////////////////////////////////////////
231 PT(GraphicsStateGuardian) glxGraphicsPipe::
232 make_callback_gsg(GraphicsEngine *engine) {
233  // We create a PosixGraphicsStateGuardian instead of a
234  // glxGraphicsStateGuardian, because the externally-created context
235  // might not have anything to do with the glx interface.
236  return new PosixGraphicsStateGuardian(engine, this);
237 }
This graphics pipe represents the interface for creating OpenGL graphics windows on an X-based (e...
This graphics pipe represents the interface for creating graphics windows on an X-based client...
A tiny specialization on GLGraphicsStateGuardian to add some glx-specific information.
An offscreen buffer in the GLX environment.
This GSG is used only for CallbackGraphicsWindow (which might not be using the glx interfaces)...
A container for the various kinds of properties we might ask to have on a graphics window before we o...
An object to create GraphicsOutputs that share a particular 3-D API.
Definition: graphicsPipe.h:58
This is a base class for the various different classes that represent the result of a frame of render...
virtual string get_interface_name() const
Returns the name of the rendering interface associated with this GraphicsPipe.
Encapsulates all the communication with a particular instance of a given rendering backend...
This class is the main interface to controlling the render process.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An interface to the glx system for managing GL windows under X.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
Another offscreen buffer in the GLX environment.