00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "glxGraphicsPixmap.h"
00016 #include "glxGraphicsWindow.h"
00017 #include "glxGraphicsStateGuardian.h"
00018 #include "config_glxdisplay.h"
00019 #include "glxGraphicsPipe.h"
00020
00021 #include "graphicsPipe.h"
00022 #include "glgsg.h"
00023 #include "pStatTimer.h"
00024
00025 TypeHandle glxGraphicsPixmap::_type_handle;
00026
00027
00028
00029
00030
00031
00032 glxGraphicsPixmap::
00033 glxGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
00034 const string &name,
00035 const FrameBufferProperties &fb_prop,
00036 const WindowProperties &win_prop,
00037 int flags,
00038 GraphicsStateGuardian *gsg,
00039 GraphicsOutput *host) :
00040 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
00041 {
00042 glxGraphicsPipe *glx_pipe;
00043 DCAST_INTO_V(glx_pipe, _pipe);
00044 _display = glx_pipe->get_display();
00045 _drawable = None;
00046 _x_pixmap = None;
00047 _glx_pixmap = None;
00048
00049
00050
00051 _screenshot_buffer_type = _draw_buffer_type;
00052 }
00053
00054
00055
00056
00057
00058
00059 glxGraphicsPixmap::
00060 ~glxGraphicsPixmap() {
00061 nassertv(_x_pixmap == None && _glx_pixmap == None);
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 bool glxGraphicsPixmap::
00074 begin_frame(FrameMode mode, Thread *current_thread) {
00075 PStatTimer timer(_make_current_pcollector, current_thread);
00076
00077 begin_frame_spam(mode);
00078 if (_gsg == (GraphicsStateGuardian *)NULL ||
00079 _glx_pixmap == None) {
00080 return false;
00081 }
00082
00083 glxGraphicsStateGuardian *glxgsg;
00084 DCAST_INTO_R(glxgsg, _gsg, false);
00085 glXMakeCurrent(_display, _glx_pixmap, glxgsg->_context);
00086
00087
00088
00089
00090
00091 glxgsg->reset_if_new();
00092
00093 if (mode == FM_render) {
00094 CDLockedReader cdata(_cycler);
00095 for (size_t i = 0; i != cdata->_textures.size(); ++i) {
00096 const RenderTexture &rt = cdata->_textures[i];
00097 RenderTextureMode rtm_mode = rt._rtm_mode;
00098 if (rtm_mode == RTM_bind_or_copy) {
00099 CDWriter cdataw(_cycler, cdata, false);
00100 nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
00101 cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
00102 }
00103 }
00104 clear_cube_map_selection();
00105 }
00106
00107 _gsg->set_current_properties(&get_fb_properties());
00108 return _gsg->begin_frame(current_thread);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118 void glxGraphicsPixmap::
00119 end_frame(FrameMode mode, Thread *current_thread) {
00120 end_frame_spam(mode);
00121 nassertv(_gsg != (GraphicsStateGuardian *)NULL);
00122
00123 if (mode == FM_render) {
00124 copy_to_textures();
00125 }
00126
00127 _gsg->end_frame(current_thread);
00128
00129 if (mode == FM_render) {
00130 trigger_flip();
00131 clear_cube_map_selection();
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 void glxGraphicsPixmap::
00142 close_buffer() {
00143 if (_gsg != (GraphicsStateGuardian *)NULL) {
00144 glXMakeCurrent(_display, None, NULL);
00145 _gsg.clear();
00146 }
00147
00148 if (_glx_pixmap != None) {
00149 glXDestroyGLXPixmap(_display, _glx_pixmap);
00150 _glx_pixmap = None;
00151 }
00152
00153 if (_x_pixmap != None) {
00154 XFreePixmap(_display, _x_pixmap);
00155 _x_pixmap = None;
00156 }
00157
00158 _is_valid = false;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168 bool glxGraphicsPixmap::
00169 open_buffer() {
00170 glxGraphicsPipe *glx_pipe;
00171 DCAST_INTO_R(glx_pipe, _pipe, false);
00172
00173
00174 glxGraphicsStateGuardian *glxgsg;
00175 if (_gsg == 0) {
00176
00177 glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
00178 glxgsg->choose_pixel_format(_fb_properties, _display, glx_pipe->get_screen(), false, true);
00179 _gsg = glxgsg;
00180 } else {
00181
00182
00183 DCAST_INTO_R(glxgsg, _gsg, false);
00184 if (!glxgsg->_context_has_pixmap ||
00185 !glxgsg->get_fb_properties().subsumes(_fb_properties)) {
00186 glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
00187 glxgsg->choose_pixel_format(_fb_properties, _display, glx_pipe->get_screen(), false, true);
00188 _gsg = glxgsg;
00189 }
00190 }
00191
00192 if (!glxgsg->_context_has_pixmap) {
00193
00194 return false;
00195 }
00196
00197 XVisualInfo *visual_info = glxgsg->_visual;
00198 if (visual_info == NULL) {
00199
00200 glxdisplay_cat.error()
00201 << "No X visual: cannot create pixmap.\n";
00202 return false;
00203 }
00204
00205 _drawable = glx_pipe->get_root();
00206 if (_host != NULL) {
00207 if (_host->is_of_type(glxGraphicsWindow::get_class_type())) {
00208 glxGraphicsWindow *win = DCAST(glxGraphicsWindow, _host);
00209 _drawable = win->get_xwindow();
00210 } else if (_host->is_of_type(glxGraphicsPixmap::get_class_type())) {
00211 glxGraphicsPixmap *pix = DCAST(glxGraphicsPixmap, _host);
00212 _drawable = pix->_drawable;
00213 }
00214 }
00215
00216 _x_pixmap = XCreatePixmap(_display, _drawable,
00217 _x_size, _y_size, visual_info->depth);
00218 if (_x_pixmap == None) {
00219 glxdisplay_cat.error()
00220 << "Failed to create X pixmap.\n";
00221 close_buffer();
00222 return false;
00223 }
00224
00225 if (glxgsg->_fbconfig) {
00226
00227 _glx_pixmap = glxgsg->_glXCreatePixmap(_display, glxgsg->_fbconfig, _x_pixmap, NULL);
00228 } else {
00229
00230 _glx_pixmap = glXCreateGLXPixmap(_display, visual_info, _x_pixmap);
00231 }
00232
00233 if (_glx_pixmap == None) {
00234 glxdisplay_cat.error()
00235 << "Failed to create GLX pixmap.\n";
00236 close_buffer();
00237 return false;
00238 }
00239
00240 int error_count = x11GraphicsPipe::disable_x_error_messages();
00241 glXMakeCurrent(_display, _glx_pixmap, glxgsg->_context);
00242 if (x11GraphicsPipe::enable_x_error_messages() != error_count) {
00243
00244
00245 close_buffer();
00246 return false;
00247 }
00248
00249 glxgsg->reset_if_new();
00250 if (!glxgsg->is_valid()) {
00251 close_buffer();
00252 return false;
00253 }
00254 if (!glxgsg->get_fb_properties().verify_hardware_software
00255 (_fb_properties, glxgsg->get_gl_renderer())) {
00256 close_buffer();
00257 return false;
00258 }
00259 _fb_properties = glxgsg->get_fb_properties();
00260
00261 _is_valid = true;
00262 return true;
00263 }