00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "glxGraphicsWindow.h"
00016 #include "glxGraphicsStateGuardian.h"
00017 #include "config_glxdisplay.h"
00018 #include "glxGraphicsPipe.h"
00019
00020 #include "graphicsPipe.h"
00021 #include "keyboardButton.h"
00022 #include "mouseButton.h"
00023 #include "glgsg.h"
00024 #include "clockObject.h"
00025 #include "pStatTimer.h"
00026 #include "textEncoder.h"
00027 #include "throw_event.h"
00028 #include "lightReMutexHolder.h"
00029
00030 #include <errno.h>
00031 #include <sys/time.h>
00032
00033 TypeHandle glxGraphicsWindow::_type_handle;
00034
00035
00036
00037
00038
00039
00040 glxGraphicsWindow::
00041 glxGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
00042 const string &name,
00043 const FrameBufferProperties &fb_prop,
00044 const WindowProperties &win_prop,
00045 int flags,
00046 GraphicsStateGuardian *gsg,
00047 GraphicsOutput *host) :
00048 x11GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 bool glxGraphicsWindow::
00062 begin_frame(FrameMode mode, Thread *current_thread) {
00063 PStatTimer timer(_make_current_pcollector, current_thread);
00064
00065 begin_frame_spam(mode);
00066 if (_gsg == (GraphicsStateGuardian *)NULL) {
00067 return false;
00068 }
00069 if (_awaiting_configure) {
00070
00071
00072 return false;
00073 }
00074
00075 glxGraphicsStateGuardian *glxgsg;
00076 DCAST_INTO_R(glxgsg, _gsg, false);
00077 {
00078 LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
00079
00080 if (glXGetCurrentDisplay() == _display &&
00081 glXGetCurrentDrawable() == _xwindow &&
00082 glXGetCurrentContext() == glxgsg->_context) {
00083
00084
00085 } else {
00086
00087 glXMakeCurrent(_display, _xwindow, glxgsg->_context);
00088 }
00089 }
00090
00091
00092
00093
00094
00095 glxgsg->reset_if_new();
00096
00097 if (mode == FM_render) {
00098
00099 clear_cube_map_selection();
00100 }
00101
00102 _gsg->set_current_properties(&get_fb_properties());
00103 return _gsg->begin_frame(current_thread);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 void glxGraphicsWindow::
00117 end_flip() {
00118 if (_gsg != (GraphicsStateGuardian *)NULL && _flip_ready) {
00119
00120
00121
00122
00123
00124
00125
00126 LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
00127 glXSwapBuffers(_display, _xwindow);
00128 }
00129 GraphicsWindow::end_flip();
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 void glxGraphicsWindow::
00139 close_window() {
00140 if (_gsg != (GraphicsStateGuardian *)NULL) {
00141 glXMakeCurrent(_display, None, NULL);
00142 _gsg.clear();
00143 }
00144
00145 x11GraphicsWindow::close_window();
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 bool glxGraphicsWindow::
00156 open_window() {
00157 glxGraphicsPipe *glx_pipe;
00158 DCAST_INTO_R(glx_pipe, _pipe, false);
00159
00160
00161 glxGraphicsStateGuardian *glxgsg;
00162 if (_gsg == 0) {
00163
00164 glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
00165 glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), false, false);
00166 _gsg = glxgsg;
00167 } else {
00168
00169
00170 DCAST_INTO_R(glxgsg, _gsg, false);
00171 if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
00172 glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
00173 glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), false, false);
00174 _gsg = glxgsg;
00175 }
00176 }
00177
00178 if (glxgsg->_context == NULL) {
00179
00180 glxdisplay_cat.error()
00181 << "No GLX context: cannot open window.\n";
00182 return false;
00183 }
00184
00185 _visual_info = glxgsg->_visual;
00186 if (_visual_info == NULL) {
00187
00188 glxdisplay_cat.error()
00189 << "No X visual: cannot open window.\n";
00190 return false;
00191 }
00192 Visual *visual = _visual_info->visual;
00193
00194 if (glxgsg->_fbconfig != None) {
00195 setup_colormap(glxgsg->_fbconfig);
00196 } else {
00197 setup_colormap(_visual_info);
00198 }
00199
00200 if (!x11GraphicsWindow::open_window()) {
00201 return false;
00202 }
00203
00204 glXMakeCurrent(_display, _xwindow, glxgsg->_context);
00205 glxgsg->reset_if_new();
00206 if (!glxgsg->is_valid()) {
00207 close_window();
00208 return false;
00209 }
00210 if (!glxgsg->get_fb_properties().verify_hardware_software
00211 (_fb_properties, glxgsg->get_gl_renderer())) {
00212 close_window();
00213 return false;
00214 }
00215 _fb_properties = glxgsg->get_fb_properties();
00216
00217 return true;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 void glxGraphicsWindow::
00227 setup_colormap(GLXFBConfig fbconfig) {
00228 glxGraphicsStateGuardian *glxgsg;
00229 DCAST_INTO_V(glxgsg, _gsg);
00230 nassertv(glxgsg->_supports_fbconfig);
00231
00232 XVisualInfo *visual_info = glxgsg->_glXGetVisualFromFBConfig(_display, fbconfig);
00233 if (visual_info == NULL) {
00234
00235 return;
00236 }
00237 int visual_class = visual_info->c_class;
00238 Visual *visual = visual_info->visual;
00239 XFree(visual_info);
00240
00241 glxGraphicsPipe *glx_pipe;
00242 DCAST_INTO_V(glx_pipe, _pipe);
00243 X11_Window root_window = glx_pipe->get_root();
00244
00245 int rc, is_rgb;
00246
00247 switch (visual_class) {
00248 case PseudoColor:
00249 rc = glxgsg->_glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &is_rgb);
00250 if (rc == 0 && is_rgb) {
00251 glxdisplay_cat.warning()
00252 << "mesa pseudocolor not supported.\n";
00253
00254 _colormap = (Colormap)0;
00255
00256 } else {
00257 _colormap = XCreateColormap(_display, root_window,
00258 visual, AllocAll);
00259 }
00260 break;
00261 case TrueColor:
00262 case DirectColor:
00263 _colormap = XCreateColormap(_display, root_window,
00264 visual, AllocNone);
00265 break;
00266 case StaticColor:
00267 case StaticGray:
00268 case GrayScale:
00269 _colormap = XCreateColormap(_display, root_window,
00270 visual, AllocNone);
00271 break;
00272 default:
00273 glxdisplay_cat.error()
00274 << "Could not allocate a colormap for visual class "
00275 << visual_class << ".\n";
00276 break;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 void glxGraphicsWindow::
00287 setup_colormap(XVisualInfo *visual) {
00288 glxGraphicsPipe *glx_pipe;
00289 DCAST_INTO_V(glx_pipe, _pipe);
00290 X11_Window root_window = glx_pipe->get_root();
00291
00292 int visual_class = visual->c_class;
00293 int rc, is_rgb;
00294
00295 switch (visual_class) {
00296 case PseudoColor:
00297 rc = glXGetConfig(_display, visual, GLX_RGBA, &is_rgb);
00298 if (rc == 0 && is_rgb) {
00299 glxdisplay_cat.warning()
00300 << "mesa pseudocolor not supported.\n";
00301
00302 _colormap = (Colormap)0;
00303
00304 } else {
00305 _colormap = XCreateColormap(_display, root_window,
00306 visual->visual, AllocAll);
00307 }
00308 break;
00309 case TrueColor:
00310 case DirectColor:
00311 _colormap = XCreateColormap(_display, root_window,
00312 visual->visual, AllocNone);
00313 break;
00314 case StaticColor:
00315 case StaticGray:
00316 case GrayScale:
00317 _colormap = XCreateColormap(_display, root_window,
00318 visual->visual, AllocNone);
00319 break;
00320 default:
00321 glxdisplay_cat.error()
00322 << "Could not allocate a colormap for visual class "
00323 << visual_class << ".\n";
00324 break;
00325 }
00326 }