00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eglGraphicsBuffer.h"
00016 #include "eglGraphicsStateGuardian.h"
00017 #include "config_egldisplay.h"
00018 #include "eglGraphicsPipe.h"
00019
00020 #include "graphicsPipe.h"
00021 #include "pStatTimer.h"
00022
00023 TypeHandle eglGraphicsBuffer::_type_handle;
00024
00025
00026
00027
00028
00029
00030 eglGraphicsBuffer::
00031 eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
00032 const string &name,
00033 const FrameBufferProperties &fb_prop,
00034 const WindowProperties &win_prop,
00035 int flags,
00036 GraphicsStateGuardian *gsg,
00037 GraphicsOutput *host) :
00038 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
00039 {
00040 eglGraphicsPipe *egl_pipe;
00041 DCAST_INTO_V(egl_pipe, _pipe);
00042 _pbuffer = EGL_NO_SURFACE;
00043
00044
00045
00046 _screenshot_buffer_type = _draw_buffer_type;
00047 }
00048
00049
00050
00051
00052
00053
00054 eglGraphicsBuffer::
00055 ~eglGraphicsBuffer() {
00056 nassertv(_pbuffer == EGL_NO_SURFACE);
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 bool eglGraphicsBuffer::
00069 begin_frame(FrameMode mode, Thread *current_thread) {
00070 PStatTimer timer(_make_current_pcollector, current_thread);
00071
00072 begin_frame_spam(mode);
00073 if (_gsg == (GraphicsStateGuardian *)NULL) {
00074 return false;
00075 }
00076
00077 eglGraphicsStateGuardian *eglgsg;
00078 DCAST_INTO_R(eglgsg, _gsg, false);
00079 if (!eglMakeCurrent(eglgsg->_egl_display, _pbuffer, _pbuffer, eglgsg->_context)) {
00080 egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
00081 << get_egl_error_string(eglGetError()) << "\n";
00082 }
00083
00084
00085
00086
00087
00088 eglgsg->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 eglGraphicsBuffer::
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 eglGraphicsBuffer::
00139 close_buffer() {
00140 if (_gsg != (GraphicsStateGuardian *)NULL) {
00141 eglGraphicsStateGuardian *eglgsg;
00142 DCAST_INTO_V(eglgsg, _gsg);
00143 if (!eglMakeCurrent(eglgsg->_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
00144 egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
00145 << get_egl_error_string(eglGetError()) << "\n";
00146 }
00147 _gsg.clear();
00148
00149 if (_pbuffer != EGL_NO_SURFACE) {
00150 if (!eglDestroySurface(_egl_display, _pbuffer)) {
00151 egldisplay_cat.error() << "Failed to destroy surface: "
00152 << get_egl_error_string(eglGetError()) << "\n";
00153 }
00154 _pbuffer = EGL_NO_SURFACE;
00155 }
00156 }
00157
00158 _is_valid = false;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168 bool eglGraphicsBuffer::
00169 open_buffer() {
00170 eglGraphicsPipe *egl_pipe;
00171 DCAST_INTO_R(egl_pipe, _pipe, false);
00172
00173
00174 eglGraphicsStateGuardian *eglgsg;
00175 if (_gsg == 0) {
00176
00177 eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, NULL);
00178 eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
00179 _gsg = eglgsg;
00180 } else {
00181
00182
00183 DCAST_INTO_R(eglgsg, _gsg, false);
00184 if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
00185 eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
00186 eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
00187 _gsg = eglgsg;
00188 }
00189 }
00190
00191 if (eglgsg->_fbconfig == None) {
00192
00193
00194 return false;
00195 }
00196
00197 int attrib_list[] = {
00198 EGL_WIDTH, _x_size,
00199 EGL_HEIGHT, _y_size,
00200 EGL_NONE
00201 };
00202
00203 _pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list);
00204
00205 if (_pbuffer == EGL_NO_SURFACE) {
00206 egldisplay_cat.error()
00207 << "Failed to create EGL pbuffer surface: "
00208 << get_egl_error_string(eglGetError()) << "\n";
00209 return false;
00210 }
00211
00212 if (!eglMakeCurrent(eglgsg->_egl_display, _pbuffer, _pbuffer, eglgsg->_context)) {
00213 egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
00214 << get_egl_error_string(eglGetError()) << "\n";
00215 }
00216 eglgsg->reset_if_new();
00217 if (!eglgsg->is_valid()) {
00218 close_buffer();
00219 return false;
00220 }
00221 if (!eglgsg->get_fb_properties().verify_hardware_software
00222 (_fb_properties, eglgsg->get_gl_renderer())) {
00223 close_buffer();
00224 return false;
00225 }
00226 _fb_properties = eglgsg->get_fb_properties();
00227
00228 _is_valid = true;
00229 return true;
00230 }