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